Reputation: 3199
I'm trying to create an ocaml program where a user enters input similar to command line arguments, such as......
./program
$ -s foo -i 84
$ -s bar -i 22
...basically a simple menu program.
I was hoping to be able to use ocaml Args to do this (especially with the 'usage', etc built in), but I realize this is just for the command line. Is there a way to re-purpose this library to work for in-program user input, or is it better to hack something together from the Stream/Parser library or a different solution entirely?
Upvotes: 3
Views: 2486
Reputation: 3199
Thanks to Jeffrey for the correct API call... Initially, I couldn't figure out how to use that call more than once (as in the values would get set to the first set you give ONLY), and the trick is you must use the optional argument ?current:(Some (ref 0))
to use the call more than once.
Here is my code if it helps anyone else (note I am NOT checking errors, etc):
(* default values *)
let somestr = ref ""
let someint = ref 0
let usage = "usage: set [-s string] [-d int]"
(* from http://rosettacode.org/wiki/Command-line_arguments#OCaml *)
let speclist = [
("-s", Arg.String (fun s -> somestr := s), ": follows -s sets some string");
("-d", Arg.Int (fun d -> someint := d), ": some int parameter");
]
let parseinput userinp =
(* Read the arguments *)
Printf.printf "String:%s\n" (Array.get userinp 2);
Arg.parse_argv ?current:(Some (ref 0)) userinp
speclist
(fun x -> raise (Arg.Bad ("Bad argument : " ^ x)))
usage;
Printf.printf "Set stuff to: %d '%s'\n%!" !someint !somestr
let parseit line =
Printf.printf "processing %s%!\n" line;
(* TODO rewrite without Str*)
let listl = (Str.split (Str.regexp " ") line) in
parseinput (Array.of_list listl)
let _ =
try
while true do
let line = input_line stdin in
parseit line
done;
None
with
End_of_file -> None
Compile:
ocamlc str.cma -o args args.ml
Commands to give it:
set -d 8332 -s lalalla
set -d 11111 -s fffffff
Upvotes: 3
Reputation: 66823
(Note that the module name is Arg
, not Args
.)
The function Arg.parse_argv
seems to do exactly what you want if you're willing to write code to break the line into words.
(Note that in a Unix-like system it's the shell, not the Arg
module, that breaks lines into words. So to use Arg
this way you have to do what the shell would do.)
Upvotes: 5