(**************************************************************************) (* -*- tuareg -*- *) (* *) (* Copyright (C) 2017,2018 Yann RĂ©gis-Gianas, Nicolas Jeannerod, *) (* Ralf Treinen. *) (* *) (* This is free software: you can redistribute it and/or modify it *) (* under the terms of the GNU General Public License, version 3. *) (* *) (* Additional terms apply, due to the reproduction of portions of *) (* the POSIX standard. Please refer to the file COPYING for details. *) (**************************************************************************) open API open CAPI let save input_filename (cst : CST.program) = (** write the concrete syntax tree [cst] to the output file corresponding to [input_filename]. The format and the name of the output file are determined by the program options. *) MorbigOptions.( let cout = open_out (output_file_of_input_file input_filename) in begin match backend () with | Bin -> API.save_binary_cst cout cst | Json -> API.save_json_cst cout cst | SimpleJson -> JsonHelpers.save_as_json true cout cst | Dot -> JsonHelpers.save_as_dot cout cst end; close_out cout ) let save_error input_filename message = (** write string [message] to the error file corresponding to [input_filename]. *) let eout = open_out (input_filename ^ ".morbigerror") in output_string eout message; output_string eout "\n"; close_out eout let not_a_script input_filename = MorbigOptions.skip_nosh () && (Scripts.(is_elf input_filename || is_other_script input_filename)) let nb_inputs = ref 0 let nb_inputs_skipped = ref 0 let nb_inputs_erroneous = ref 0 let show_stats () = if MorbigOptions.display_stats () then begin Printf.printf "Number of input files: %i\n" !nb_inputs; Printf.printf "Number of skipped files: %i\n" !nb_inputs_skipped; Printf.printf "Number of rejected files: %i\n" !nb_inputs_erroneous end let parse_one_file input_filename = Debug.printf "Trying to open: %s\n" input_filename; incr nb_inputs; if not_a_script input_filename then incr nb_inputs_skipped else try parse_file input_filename |> save input_filename with e -> incr nb_inputs_erroneous; if MorbigOptions.continue_after_error () then save_error input_filename (Errors.string_of_error e) else ( output_string stderr (Errors.string_of_error e ^ "\n"); exit 1 ) let parse_input_files_provided_via_stdin () = try while true do parse_one_file (read_line ()) done with End_of_file -> () let parse_input_files_provided_on_command_line () = if List.length (MorbigOptions.input_files ()) <= 0 then begin Printf.eprintf "morbig: no input files.\n"; exit 1 end; List.iter parse_one_file (MorbigOptions.input_files ()) let parse_input_files () = if MorbigOptions.from_stdin () then parse_input_files_provided_via_stdin () else parse_input_files_provided_on_command_line () let main = MorbigOptions.analyze_command_line_arguments (); parse_input_files (); show_stats ()