Note:

You are viewing a development version of the library. Goto the latest version.

let parse_and_run () =
  let pos = ref 0 in

  (* Common args. *)
  let ctxt_specs, ctxt_gen = fspecs () in
  (* Choose a command. *)
  let scmd = ref None in
  let scmd_args = ref [||] in
  let set_scmd s =
    scmd := Some (CLISubCommand.find s);

    (* Get the rest of arguments *)
    scmd_args := Array.sub Sys.argv !pos ((Array.length Sys.argv) - !pos);

    (* Skip arguments *)
    pos := !pos + Array.length !scmd_args
  in

  let handle_error exc hext =
    let get_bad str =
      match OASISString.split_newline ~do_trim:false str with
        | fst :: _ ->
            fst
        | [] ->
            s_ "Unknown error on the command line"
    in
      match exc with
        | Arg.Bad txt ->
            pp_print_help ~ctxt:(ctxt_gen ()) hext Output err_formatter ();
            prerr_newline ();
            prerr_endline (get_bad txt);
            exit 2
        | Arg.Help txt ->
            pp_print_help ~ctxt:(ctxt_gen ()) hext Output std_formatter ();
            exit 0
        | e ->
            raise e
  in
  (* Parse global options and set scmd *)
  let () =
    try
      Arg.parse_argv
        ~current:pos
        Sys.argv
        (Arg.align ctxt_specs)
        set_scmd
        usage_msg
    with e ->
      handle_error e NoSubCommand
  in

  (* Parse subcommand options *)
  let scmd =
    match !scmd with
      | Some scmd ->
          scmd
      | None ->
          failwith (s_ "No subcommand defined, call 'oasis help' for help")
  in
  let (scmd_specs, scmd_anon), main = scmd.scmd_run () in
  let () =
    try
      Arg.parse_argv
        ~current:(ref 0)
        !scmd_args
        (Arg.align scmd_specs)
        scmd_anon
        (Printf.sprintf
           (f_ "Subcommand %s options:\n")
           scmd.scmd_name)
    with e ->
      handle_error e (SubCommand scmd.scmd_name)
  in
  let ctxt = ctxt_gen () in
    if scmd.scmd_deprecated then
      warning ~ctxt "Subcommand %s is deprecated." scmd.scmd_name;
    main ~ctxt