Make the OCaml Arg.parse function take anonymous arguments starting with
I am trying to use Arg.parse
OCaml function to read command line options and arguments, including unspecified arguments starting with -
. According to the manual:
To enable the user to specify anonymous arguments that start with a -, include, for example,
("-", String anon_fun, doc)
inspeclist
.
So I expect this example to work:
let other_option x = Format.printf "Other option: %s@." x
let other_argument x = Format.printf "Other argument: %s@." x
let arg_speclist =[
("-a", Arg.Unit (fun () -> Format.printf "Known option: -a@."), "option a");
("-", Arg.String other_option, "any option")
]
let () = Arg.parse arg_speclist other_argument "Usage:"
With the specified parameter -a
and other arguments, it works:
$ ocaml test.ml arg1 -a arg2
Other argument: arg1
Known option: -a
Other argument: arg2
But that's not when trying to use something starting with -
:
$ ocaml test.ml -x test.ml: unknown option '-x'. Usage: -a option a - any option -help Display this list of options --help Display this list of options
I would expect the function to be called other_option
. What am I doing wrong?
source to share
Usage ("-", String anon_fun, doc)
doesn't let you do what you think it does, it lets you enter parameters like this:
ocaml test.ml - -x
Basically, it does an "-"
"escaping" option, which will pass the next one to anon_fun.
The exact behavior you want cannot be easily accomplished with Arg
(which has never been considered an exhaustive argument parser AFAIK).
As a possible workaround, you can manually view your argv by hand (remember not to read 0
) and dynamically add the parameters to your list:
let speclist = [ ("-option", Arg.String print_endline, "handled option") ]
let speclist =
let r = ref speclist in
for i = 1 to pred (Array.length Sys.argv) do
let s = Sys.argv.(i) in
if s.[0] = '-' && not List.exists (fun (s',_,_) -> s = s') !r
then r := (s, Arg.Unit (fun () -> anon_fun s), "any_option") :: !r
done;
!r
Another option is to get the code from Arg
and modify it to fit your model, or use another more powerful tool. Perhaps Cmdliner
- this is what you are looking for (I have never used it, so I don't know if it does the trick).
source to share