Skip to content
Snippets Groups Projects
sasArg.ml 6.23 KiB
Newer Older
(* Time-stamp: <modified the 28/03/2019 (at 17:56) by Erwan Jahier> *)


type t = {
  mutable topo: string;
  mutable length: int;
  mutable verbose: int;
  mutable demon: Demon.t;
erwan's avatar
erwan committed
  mutable seed: int;
  mutable ifi: bool;
  mutable gen_lutin: bool;
  mutable _args : (string * Arg.spec * string) list;
  mutable _user_man  : (string * string list) list; 
  mutable _hidden_man: (string * string list) list; 

  mutable _others : string list;
  mutable _margin : int;
}

let usage_msg tool = ("usage: " ^ tool ^ " [<option>]* <topology>.dot 
erwan's avatar
erwan committed
use -h to see the available options.
let print_usage tool = Printf.printf "%s\n" (usage_msg tool); flush stdout


let (make_args : unit -> t) = 
  fun () -> 
    {
      topo = "";
      verbose = 0;
      demon = Demon.Distributed;
erwan's avatar
erwan committed
      seed = (Random.self_init (); Random.int 1073741823);
      ifi = false;
      gen_lutin = false;
      _user_man  = [];   
      _hidden_man  = []; 
      _others = [];
      _margin =12;
    }


  let (m1, oth) = match ml with
	 |	h::t -> (h,t)
	 |	_ -> ("",[])
  in
  let t2 = String.make args._margin ' ' in
  let cl = String.length c in
  let t1 = if (cl < args._margin ) then
	 String.make (args._margin - cl) ' '
  else
	 "\n"^t2
  in
	 Printf.fprintf os "%s%s%s" c t1 m1;
	 List.iter (function x -> Printf.fprintf os "\n%s%s" t2 x) oth ;
	 Printf.fprintf os "\n" ;
)

	let l = List.rev args._user_man in
	let l = List.rev (args._hidden_man) in
)
let (mkopt : t -> string list -> ?hide:bool -> ?arg:string -> Arg.spec ->
     string list -> unit) =
  fun opt ol ?(hide=false) ?(arg="") se ml ->
    let treto o = opt._args <- (o, se, "")::opt._args in
	   List.iter treto ol ;
	   let col1 = (String.concat ", " ol)^arg in
	     if hide 
        then opt._hidden_man <- (col1, ml)::opt._hidden_man
	     else opt._user_man   <- (col1, ml)::opt._user_man

let myexit i = exit i

(*** User Options Tab **)
let (mkoptab : string array -> t -> unit) = 
  fun argv args ->  
    mkopt args  ["--synchronous-demon";"-sd"]
      (Arg.Unit(fun () -> args.demon <- Demon.Synchronous))
      ["Use a Synchronous deamon"];

    mkopt args  ["--central-demon";"-cd"]
      (Arg.Unit(fun () -> args.demon <- Demon.Central))
erwan's avatar
erwan committed
      ["Use a Central deamon (which selects exactly one action)"];
    mkopt args  ["--locally-central-demon";"-lcd"]
      (Arg.Unit(fun () -> args.demon <- Demon.LocallyCentral))
erwan's avatar
erwan committed
      ["Use a Locally Central deamon (which never activates two neighbors";
       "actions in the same step)"];
    mkopt args  ["--distributed-demon";"-dd"]
      (Arg.Unit(fun () -> args.demon <- Demon.Distributed))
erwan's avatar
erwan committed
      ["Use a Distributed deamon (which select at least one action)"];
    mkopt args  ["--custom-demon";"-custd"]
erwan's avatar
erwan committed
      (Arg.Unit(fun () -> args.demon <- Demon.Custom;args.rif <- true))
      ["Use a Custom deamon (forces --rif)"];
      (Arg.Unit(fun () -> args.rif <- true))
      ["Follows RIF conventions"];

erwan's avatar
erwan committed
      (Arg.Int(fun i -> args.seed <- i))
      ["Set the pseudo-random generator seed of build-in demons"];

   mkopt args ~hide:true ["--gen-lutin-demon";"-gld"]
      (Arg.Unit(fun () -> args.gen_lutin <- true))
      ["Generate Lutin demons and exit"];

   mkopt args ~hide:true ["--dummy-input"]
      (Arg.Unit(fun () -> args.dummy_input <- true))
      ["Add a dummy input to sasa so that built-in demon can be used from rdbg"];

    mkopt args ~hide:true ["--ignore-first-inputs"; "-ifi"]
      (Arg.Unit(fun () -> args.ifi <- true))
      ["Ignore first inputs (necessary to use luciole via lurette/rdbg/luciole-rif)"];

    mkopt args ["--length";"-l"] ~arg:" <int>"
      (Arg.Int (fun i -> args.length <- i))
      ["Maximum number of steps to be done (" ^ (string_of_int args.length) ^ " by default).\n"];

    mkopt args ~hide:true ["--version";"-version";"-v"]
erwan's avatar
erwan committed
      (Arg.Unit (fun _ ->
           (print_string (SasaVersion.str^"-"^SasaVersion.sha^"\n");flush stdout;exit 0)))
      ["Display the sasa version and exit."];

    mkopt args ~hide:true ["--ocaml-version"]
erwan's avatar
erwan committed
      (Arg.Unit (fun _ -> (print_string (Sys.ocaml_version^"\n"); flush stdout; exit 0)))
      ["Display the version ocaml version sasa was compiled with and exit."];

    mkopt args  ["--verbose";"-vl"] ~arg:" <int>"
      (Arg.Int (fun i -> args.verbose <- i))   ["Set the verbose level"];

    mkopt args ["--help";"-help"; "-h"]
      (Arg.Unit (fun _ -> print_usage (argv.(0)); options args stdout; exit 0))
      ["Display main options"];

    mkopt args ["--more";"-m"] (Arg.Unit (fun () -> more_options args stdout; exit 0)) 
      ["Display more options"]

  )

(* all unrecognized options are accumulated *)
let (add_other : t -> string -> unit) =
  fun opt s -> 
    opt._others <- s::opt._others

let current = ref 0;;
let first_line b = (
	try (
		let f = String.index b '\n' in
		String.sub b 0 f
	) with Not_found -> b
)
let file_notfound f = (
	prerr_string ("File not found: \""^f^"\"");
	prerr_newline ();
	myexit 1
)
let unexpected s = (
	prerr_string ("unexpected argument \""^s^"\"");
	prerr_newline ();
	myexit 1
)

let parse argv = (
  let save_current = !current in
  try (
    let args = make_args () in 
    mkoptab argv args;
	 Arg.parse_argv ~current:current argv args._args (add_other args) (usage_msg argv.(0));
    (List.iter 
       (fun f -> 
         if (String.sub f 0 1 = "-") then
           unexpected f 
         else if not (Sys.file_exists f) then
           file_notfound f
         else ()
       ) 
       args._others);
    current := save_current;
    args.topo <- (match args._others with
          [] -> 
          Printf.fprintf stderr "*** The topology file is missing in '%s'\n%s\n"
            (argv.(0)) (usage_msg argv.(0));  
          exit 2; 
        | x::_ -> x
  )
  with
  | Arg.Bad msg ->
    Printf.fprintf stderr "*** Error when calling '%s': %s\n%s\n" (argv.(0))
      (first_line msg) (usage_msg argv.(0)); exit 2; 
  | Arg.Help msg -> 
    Printf.fprintf stdout "%s\n%s\n" msg (usage_msg argv.(0)); 
    exit 0