Newer
Older
(* Small script to test that the code generated by aorai can be parsed again
* by frama-c.
open Kernel
module P = Plugin.Register
(struct
let name = "aorai testing module"
let shortname = "aorai-test"
let help = "utility script for aorai regtests"
end)
module TestNumber =
(struct
let option_name = "-aorai-test-number"
let help = "test number when multiple tests are run over the same file"
let arg_name = "n"
module InternalWpShare =
struct
let option_name = "-aorai-test-wp-share"
let help = "use custom wp share dir (when in internal plugin mode)"
let arg_name = "dir"
let existence = Filepath.Must_exist
let file_kind = "wp share directory"
end)
module WpCache =
P.Filepath(
struct
let option_name = "-aorai-test-wp-cache"
let help = "use custom session dir for storing cache"
let arg_name = "dir"
let existence = Filepath.Must_exist
let file_kind = "wp session directory"
end)
module ProveAuxSpec =
struct
let option_name = "-aorai-test-prove-aux-spec"
let help = "use WP + alt-ergo to prove that generated spec and body \
of auxiliary automata functions match"
end)
let ok = ref false
let is_suffix suf str =
let lsuf = String.length suf in
let lstr = String.length str in
if lstr <= lsuf then false
else
let estr = String.sub str (lstr - lsuf) lsuf in
estr = suf
let extend () =
let myrun =
let run = !Db.Toplevel.run in
fun f ->
let my_project = Project.create "Reparsing" in
let wp_compute_kf kf =
let vcs = Wp.VC.generate_kf kf in
Wp.VC.command vcs;
Bag.iter
(fun vc ->
if not (Wp.VC.is_proved vc) then
P.warning "Could not prove %a in automaton function %a"
Property.pretty (Wp.VC.get_property vc)
Kernel_function.pretty kf)
vcs
in
let check_auto_func kf =
let name = Kernel_function.get_name kf in
if Kernel_function.is_definition kf &&
(is_suffix "_pre_func" name || is_suffix "_post_func" name)
then
let tmpdir = Filename.get_temp_dir_name () in
let tmpdir =
match Filename.chop_suffix_opt ~suffix:"/" tmpdir with
| None -> tmpdir
| Some dir -> dir
in
let tmpfile =
tmpdir ^ "/aorai_" ^
Filename.(
chop_extension (basename (List.hd (Kernel.Files.get()):>string))) ^
"_" ^ (string_of_int (TestNumber.get ())) ^ ".i"
in
let () =
Extlib.safe_at_exit
(fun () ->
if Debug.get () >= 1 || not !ok then
result "Keeping temp file %s" tmpfile
else Extlib.safe_remove tmpfile)
in
let chan = open_out tmpfile in
let fmt = Format.formatter_of_out_channel chan in
let aorai_prj = Project.from_unique_name "aorai" in
Project.on aorai_prj Kernel.PrintLibc.on ();
File.pretty_ast ~prj:aorai_prj ~fmt ();
close_out chan;
let selection =
List.fold_left
(fun selection state ->
State_selection.union
(State_selection.with_codependencies state) selection)
State_selection.empty
[ InternalWpShare.self; ProveAuxSpec.self; WpCache.self ]
in
Project.copy ~selection my_project;
Project.set_current my_project;
Kernel.SymbolicPath.add
(Filepath.Normalized.of_string (Filename.get_temp_dir_name ()),
Some "TMPDIR");
Files.append_after [ Filepath.Normalized.of_string tmpfile ];
Constfold.off ();
Ast.compute();
if ProveAuxSpec.get () then begin
if InternalWpShare.is_set() then
Wp.Wp_parameters.Share.set (InternalWpShare.get());
Wp.Wp_parameters.Let.off();
Wp.Wp_parameters.Split.on();
Wp.Wp_parameters.SplitMax.set 32;
if WpCache.is_set () then
Wp.Wp_parameters.Session.set (WpCache.get());
Wp.Wp_parameters.Cache.set "update";
Globals.Functions.iter check_auto_func;
end else begin
File.pretty_ast ();
end;
ok:=true (* no error, we can erase the file *)
in
Db.Toplevel.run := myrun
let () = extend ()