summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--stdlib/arg.ml45
-rw-r--r--stdlib/arg.mli13
2 files changed, 40 insertions, 18 deletions
diff --git a/stdlib/arg.ml b/stdlib/arg.ml
index 86c8255f5..b6ddd3dd6 100644
--- a/stdlib/arg.ml
+++ b/stdlib/arg.ml
@@ -38,6 +38,7 @@ type spec =
function with each remaining argument *)
exception Bad of string
+exception Help of string
type error =
| Unknown of string
@@ -60,43 +61,51 @@ let make_symlist prefix sep suffix l =
| h::t -> (List.fold_left (fun x y -> x ^ sep ^ y) (prefix ^ h) t) ^ suffix
;;
-let print_spec (key, spec, doc) =
+let print_spec buf (key, spec, doc) =
match spec with
- | Symbol (l, _) -> eprintf " %s %s %s\n" key (make_symlist "{" "|" "}" l) doc
- | _ -> eprintf " %s %s\n" key doc
+ | Symbol (l, _) -> bprintf buf " %s %s %s\n" key (make_symlist "{" "|" "}" l)
+ doc
+ | _ -> bprintf buf " %s %s\n" key doc
;;
-let usage speclist errmsg =
- eprintf "%s\n" errmsg;
- List.iter print_spec speclist;
+let usage_b buf speclist errmsg =
+ bprintf buf "%s\n" errmsg;
+ List.iter (print_spec buf) speclist;
try ignore (assoc3 "-help" speclist)
- with Not_found -> eprintf " -help Display this list of options\n";
+ with Not_found -> bprintf buf " -help Display this list of options\n";
try ignore (assoc3 "--help" speclist)
- with Not_found -> eprintf " --help Display this list of options\n";
+ with Not_found -> bprintf buf " --help Display this list of options\n";
+;;
+
+let usage speclist errmsg =
+ let b = Buffer.create 200 in
+ usage_b b speclist errmsg;
+ eprintf "%s" (Buffer.contents b);
;;
let current = ref 0;;
let parse_argv argv speclist anonfun errmsg =
+ let b = Buffer.create 200 in
let stop error =
let progname = if Array.length argv > 0 then argv.(0) else "(?)" in
begin match error with
| Unknown "-help" -> ()
| Unknown "--help" -> ()
| Unknown s ->
- eprintf "%s: unknown option `%s'.\n" progname s
+ bprintf b "%s: unknown option `%s'.\n" progname s
| Missing s ->
- eprintf "%s: option `%s' needs an argument.\n" progname s
+ bprintf b "%s: option `%s' needs an argument.\n" progname s
| Wrong (opt, arg, expected) ->
- eprintf "%s: wrong argument `%s'; option `%s' expects %s.\n"
+ bprintf b "%s: wrong argument `%s'; option `%s' expects %s.\n"
progname arg opt expected
| Message s ->
- eprintf "%s: %s.\n" progname s
+ bprintf b "%s: %s.\n" progname s
end;
- usage speclist errmsg;
+ usage_b b speclist errmsg;
if error = Unknown "-help" || error = Unknown "--help"
- then exit 0
- else exit 2
+ then raise (Help (Buffer.contents b))
+ else raise (Bad (Buffer.contents b))
in
let l = Array.length argv in
incr current;
@@ -178,5 +187,9 @@ let parse_argv argv speclist anonfun errmsg =
let parse =
current := 0;
- parse_argv Sys.argv;
+ try
+ parse_argv Sys.argv;
+ with
+ | Bad msg -> eprintf "%s" msg; exit 0;
+ | Help msg -> eprintf "%s" msg; exit 2;
;;
diff --git a/stdlib/arg.mli b/stdlib/arg.mli
index 58d71e161..fa54cebc4 100644
--- a/stdlib/arg.mli
+++ b/stdlib/arg.mli
@@ -99,11 +99,20 @@ val parse_argv : string array ->
(** [Arg.parse_argv args speclist anon_fun usage_msg] parses the array
[args] as if it were the command line. It uses and updates the
value of [Arg.current]. You must set [Arg.current] before calling
- [parse_argv], and restore it afterward if needed. *)
+ [parse_argv], and restore it afterward if needed.
+ If an error occurs, [Arg.parse_argv] raises [Arg.Bad] with
+ the error message as argument. If option [-help] or [--help] is
+ given, [Arg.parse_argv] raises [Arg.Help] with the help message
+ as argument.
+*)
+
+exception Help of string
+(** Raised by [Arg.parse_argv] when the user asks for help. *)
exception Bad of string
(** Functions in [spec] or [anon_fun] can raise [Arg.Bad] with an error
- message to reject invalid arguments. *)
+ message to reject invalid arguments.
+ [Arg.Bad] is also raised by [Arg.parse_argv] in case of an error. *)
val usage : (key * spec * doc) list -> usage_msg -> unit
(** [Arg.usage speclist usage_msg] prints an error message including