Revision ad0c16675d221938530269610308cd5a2c142687 authored by Software Heritage on 17 October 2018, 13:20:37 UTC, committed by Software Heritage on 17 October 2018, 13:20:37 UTC
0 parent
Raw File
morbigDriver.ml
(**************************************************************************)
(*  -*- 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 ()
back to top