let parse_cmd_args () =
  let argv = Sys.argv in
  let argc = Array.length argv in
  if argc = 1 then help ();
  let parsing = ref true in
  let i = ref 0 in

  let base_env = ref "" in
  let compile_only = ref false in
  let program = ref "" in
  let output = ref "out.fnf" in

  while !parsing do
    incr i;
    if argc = !i then Report.fatal ("** Invalid Argument: Expecting program filename.");
    match argv.(!i) with
    | "-h"
    | "-help" -> help ()

    | "-b"
    | "-base_env" ->
        if argc = !i + 1 then Report.fatal ("** Invalid Argument: Expecting base environment filename.");
        base_env := argv.(!i + 1);
        incr i

    | "-c"
    | "-compile_only" -> compile_only := true

    | "-e"
    | "-error_limit" ->
        if argc = !i + 1 then Report.fatal ("** Invalid Argument: Expecting error limit number.");
        (try
          Report.set_error_limit (int_of_string argv.(!i + 1))
        with _ -> Report.fatal ("** Invalid Argument: Expecting integer error limit."));
        incr i

    | "-o" ->
        if argc = !i + 1 then Report.fatal ("** Invalid Argument: Expecting output filename.");
        output := argv.(!i + 1);
        incr i

    | "-test" ->
        Test_suite.run ();
        exit 0

    | file ->
        program := file;
        parsing := false
  done;
  incr i;
  CfPrims.set_argv_position !i;
  if !base_env = "" then base_env := (try Sys.getenv "CF_ENV" with Not_found -> "/usr/share/confluence/base.cf");
  CfParserUtil.set_base_env !base_env;
  !program, !compile_only, !output