Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

lustrec / src / main_lustre_testgen.ml @ 0bd19a92

History | View | Annotate | Download (6.84 KB)

1 40d33d55 xavier.thirioux
(********************************************************************)
2
(*                                                                  *)
3
(*  The LustreC compiler toolset   /  The LustreC Development Team  *)
4
(*  Copyright 2012 -    --   ONERA - CNRS - INPT                    *)
5
(*                                                                  *)
6
(*  LustreC is free software, distributed WITHOUT ANY WARRANTY      *)
7
(*  under the terms of the GNU Lesser General Public License        *)
8
(*  version 2.1.                                                    *)
9
(*                                                                  *)
10
(********************************************************************)
11
12
(* This module is used for the lustre test generator *)
13
14
open Format
15
open Log
16
17
open Utils
18 8446bf03 ploc
open Lustre_types
19 40d33d55 xavier.thirioux
open Compiler_common
20
21
let usage = "Usage: lustret [options] \x1b[4msource file\x1b[0m"
22
23
let extensions = [".lus"]
24
25 55a8633c ploc
let pp_trace trace_filename mutation_list = 
26
  let trace_file = open_out trace_filename in
27
  let trace_fmt = formatter_of_out_channel trace_file in
28
  Format.fprintf trace_fmt "@[<v 2>{@ %a@ }@]"
29
    (fprintf_list
30
       ~sep:",@ "
31
       (fun fmt (mutation, mutation_loc, mutant_name) ->
32
	 Format.fprintf fmt "\"%s\": { @[<v 0>%a,@ %a@ }@]" 
33
	   mutant_name
34
	   Mutation.print_directive_json mutation
35
	   Mutation.print_loc_json mutation_loc
36
       ))
37
    mutation_list;
38
  Format.fprintf trace_fmt "@.@?" 
39
  
40 40d33d55 xavier.thirioux
  
41
let testgen_source dirname basename extension =
42
  let source_name = dirname ^ "/" ^ basename ^ extension in
43
44
  Log.report ~level:1 (fun fmt -> fprintf fmt "@[<v>");
45
46
  (* Parsing source *)
47
  let prog = parse_source source_name in
48 55a8633c ploc
  let prog, dependencies = Compiler_stages.stage1 prog dirname basename in
49 40d33d55 xavier.thirioux
50 55a8633c ploc
  (* Two cases
51
     - generation of coverage conditions
52
     - generation of mutants: a number of mutated lustre files 
53
  *)
54
  
55 40d33d55 xavier.thirioux
  if !Options.gen_mcdc then (
56 3e1d20e0 ploc
    let prog_mcdc = PathConditions.mcdc prog in
57 cda2fcc8 ploc
    (* We re-type the fresh equations *)
58 5d5139a5 ploc
    let _, type_env, _ = import_dependencies prog_mcdc in
59 3e1d20e0 ploc
    let _ = type_decls type_env prog_mcdc in
60
61
    let destname = !Options.dest_dir ^ "/" ^ basename in
62 cda2fcc8 ploc
    let source_file = destname ^ ".mcdc" in (* Could be changed *)
63
64
    (* Modified Lustre is produced in fresh .lus file *)
65
    let source_lus = source_file ^ ".lus" in
66
    let source_out = open_out source_lus in
67 3e1d20e0 ploc
    let fmt = formatter_of_out_channel source_out in
68
    Printers.pp_prog fmt prog_mcdc;
69
    Format.fprintf fmt "@.@?";
70 cda2fcc8 ploc
71
    (* Prog is 
72
       (1) cleaned from initial equations TODO
73
       (2) produced as EMF
74
    *)
75
    Options.output := "emf";
76
    let prog_mcdc = Normalization.normalize_prog ~backend:"emf" prog_mcdc in
77
    let machine_code = Compiler_stages.stage2 prog_mcdc in
78
    let source_emf = source_file ^ ".emf" in 
79
    let source_out = open_out source_emf in
80
    let fmt = formatter_of_out_channel source_out in
81
    EMF_backend.translate fmt basename prog_mcdc machine_code;
82
83 40d33d55 xavier.thirioux
    exit 0
84
  ) ;
85 55a8633c ploc
86
  
87 40d33d55 xavier.thirioux
  (* generate mutants *)
88 55a8633c ploc
  let mutants = Mutation.mutate !Options.nb_mutants prog in
89 40d33d55 xavier.thirioux
  
90
  (* Print generated mutants in target directory. *)
91
  let cpt = ref 0 in
92 55a8633c ploc
  let mutation_list =
93
    List.map (fun (mutation, mutation_loc, mutant) ->
94 40d33d55 xavier.thirioux
    (* Debugging code *)
95
    (* if List.mem !cpt [238;371;601;799;875;998] then *)
96
    (*   Format.eprintf "Mutant %i: %a -> %a" !cpt Printers.pp_expr orig_e Printers.pp_expr new_e  *)
97
    (* ; *)
98 ef8ef3ed ploc
      incr cpt;
99
      let mutant_basename = (Filename.basename basename)^ ".mutant.n" ^ (string_of_int !cpt) ^ extension  in
100
      let mutant_filename = 
101
	match !Options.dest_dir with
102
	| "" -> (* Mutants are generated in source directory *)
103
	   basename^ ".mutant.n" ^ (string_of_int !cpt) ^ extension 
104 40d33d55 xavier.thirioux
      | dir ->  (* Mutants are generated in target directory *)
105 ef8ef3ed ploc
	 dir ^ "/" ^ mutant_basename 
106 40d33d55 xavier.thirioux
    in
107
    let mutant_out = (
108
      try 
109
	open_out mutant_filename 
110
      with
111
	Sys_error _ -> Format.eprintf "Unable to open file %s for writing.@." mutant_filename; exit 1
112
    )
113
    in
114
    let mutant_fmt = formatter_of_out_channel mutant_out in
115 55a8633c ploc
    report ~level:1 (fun fmt -> fprintf fmt ".. generating mutant %s: %a@,@?"
116
      mutant_filename
117
      Mutation.print_directive mutation
118
    );
119
    Format.fprintf mutant_fmt "%a@." Printers.pp_prog mutant;
120 ef8ef3ed ploc
    mutation, mutation_loc, mutant_basename
121 55a8633c ploc
    )
122
      mutants
123
  in
124 40d33d55 xavier.thirioux
  Log.report ~level:1 (fun fmt -> fprintf fmt ".. done @ @]@.");
125 55a8633c ploc
  
126
  (* Printing traceability *)
127
  let trace_filename = 
128 ef8ef3ed ploc
    match !Options.dest_dir with
129
    | "" -> (* Mutant report is generated in source directory *)
130
       basename^ ".mutation.json" 
131
    | dir ->  (* Mutants are generated in target directory *)
132
       dir ^ "/" ^ (Filename.basename basename)^ ".mutation.json"
133 55a8633c ploc
  in
134
  pp_trace trace_filename mutation_list;
135 5487dd79 ploc
136
  (* Printing the CMakeLists.txt file *)
137
  let cmakelists = 
138
    (if !Options.dest_dir = "" then "" else !Options.dest_dir ^ "/") ^ "CMakeLists.txt"
139
  in
140
  let cmake_file = open_out cmakelists in
141
  let cmake_fmt = formatter_of_out_channel cmake_file in
142
  Format.fprintf cmake_fmt "cmake_minimum_required(VERSION 3.5)@.";
143
  Format.fprintf cmake_fmt "include(\"/home/ploc/Local/share/helpful_functions.cmake\")@.";
144
  Format.fprintf cmake_fmt "include(\"/home/ploc/Local/share/FindLustre.cmake\")@."; 
145
  Format.fprintf cmake_fmt "LUSTREFILES(LFILES ${CMAKE_CURRENT_SOURCE_DIR} )@.";
146
  Format.fprintf cmake_fmt "@[<v 2>FOREACH(lus_file ${LFILES})@ ";
147
  Format.fprintf cmake_fmt "get_lustre_name_ext(${lus_file} L E)@ ";
148 5d5139a5 ploc
  Format.fprintf cmake_fmt "Lustre_Compile(@[<v 0>@ ";
149
  if !Options.main_node <> "" then Format.fprintf cmake_fmt "NODE \"%s_mutant\"@ " !Options.main_node;
150
  Format.fprintf cmake_fmt "LIBNAME \"${L}_%s_mutant\"@ " !Options.main_node;
151 5487dd79 ploc
  Format.fprintf cmake_fmt "LUS_FILES \"${lus_file}\")@]@]@.";
152
  Format.fprintf cmake_fmt "ENDFOREACH()@.@?";
153
  
154
  
155 55a8633c ploc
  (* We stop the process here *)
156 40d33d55 xavier.thirioux
  exit 0
157 55a8633c ploc
    
158 40d33d55 xavier.thirioux
let testgen dirname basename extension =
159
  match extension with
160
  | ".lus"   -> testgen_source dirname basename extension
161
  | _        -> assert false
162
163
let anonymous filename =
164
  let ok_ext, ext = List.fold_left
165
    (fun (ok, ext) ext' ->
166
      if not ok && Filename.check_suffix filename ext' then
167
	true, ext'
168
      else
169
	ok, ext)
170
    (false, "") extensions in
171
  if ok_ext then
172
    let dirname = Filename.dirname filename in
173
    let basename = Filename.chop_suffix (Filename.basename filename) ext in
174
    testgen dirname basename ext
175
  else
176
    raise (Arg.Bad ("Can only compile *.lus files"))
177
178
let _ =
179
  Global.initialize ();
180
  Corelang.add_internal_funs ();
181
  try
182
    Printexc.record_backtrace true;
183
184 1bff14ac ploc
    let options = Options_management.lustret_options
185 40d33d55 xavier.thirioux
186
    in
187
    
188
    Arg.parse options anonymous usage
189
  with
190
  | Parse.Error _
191
  | Types.Error (_,_) | Clocks.Error (_,_)
192
  | Corelang.Error _ (*| Task_set.Error _*)
193
  | Causality.Error _ -> exit 1
194
  | Sys_error msg -> (eprintf "Failure: %s@." msg)
195 990210f3 ploc
  | exc -> (track_exception (); raise exc)
196 40d33d55 xavier.thirioux
197
(* Local Variables: *)
198
(* compile-command:"make -C .." *)
199
(* End: *)