[m-rev.] for review: structured errors for getopt and getopt_io
Julien Fischer
jfischer at opturion.com
Tue Jun 10 14:20:17 AEST 2014
Branches: master
I posted an initial version of this several months ago -- the main change
in this version is to extend the change to cover the getopt module.
-----------------------------------------
Structured errors for getopt and getopt_io.
The getopt and getopt_io modules use strings to describe errors that occur
during option processing. There are a couple of problems with doing this:
(1) it makes some assumptions about how client programs want to word, and to a
large extent, format these error messages.
(2) it assumes that the error messages are in English.
This diff changes the getopt and getopt_io modules to use structured
representations of errors instead of strings. This structured representation
is defined by the new option_error/1 type. We introduce new versions of the
various process_options predicates that are suffixed with "_se" (standing for
"structured error") that return values of type option_error/1 when an error occurs.
A new function, option_error_to_string/1, converts option_error/1 values into
the strings that the getopt and getopt_io modules previously generated. The
existing process_options predicates are just wrappers around all of this for
the purposes of backwards compatibility.
The new option_error/1 type returns more information than existing error
messages require, for example, where possible we return both the element of the
option enumeration involved and a string giving the option as it actually
appeared on the command line.
library/getopt.m:
library/getopt_io.m:
Add predicates and types for structured errors as described above.
Group function clauses together with the corresponding predicate
ones.
Avoid unnecessary differences between these two modules in a few
spots.
NEWS:
Announce the above changes.
Julien.
diff --git a/NEWS b/NEWS
index 74494ac..c1c8228 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,11 @@ NEWS since Mercury 14.01.x
Changes to the Mercury standard library:
+* We have added variants of the process_options predicates to the getopt
+ and getopt_io modules that represent errors using a type instead of strings.
+ A new function, option_error_to_string/1, can be used to convert values
+ of the new error type into strings.
+
* We have added the print_line and write_line family of predicates to the
io module. These behave like the print and write predicates, but also
write a terminating newline character.
diff --git a/library/getopt.m b/library/getopt.m
index 6287e3b..9fc647a 100644
--- a/library/getopt.m
+++ b/library/getopt.m
@@ -148,6 +148,27 @@
option_table(OptionType)::in, maybe_option_table(OptionType)::out,
set(OptionType)::out) is det.
+% Variants of the above that return structured errors.
+% These behave as the above versions except that any error values returned are
+% members of the option_error/1 type rather than strings.
+
+:- pred getopt.process_options_se(option_ops(OptionType)::in(option_ops),
+ list(string)::in, list(string)::out, maybe_option_table_se(OptionType)::out)
+ is det.
+
+:- pred getopt.process_options_se(option_ops(OptionType)::in(option_ops),
+ list(string)::in, list(string)::out, list(string)::out,
+ maybe_option_table_se(OptionType)::out) is det.
+
+% getopt.process_options_track_se(OptionOps, Args, OptionArgs,
+% NonOptionArgs, OptionTable0, Result, OptionsSet)
+
+:- pred getopt.process_options_track_se(
+ option_ops_track(OptionType)::in(option_ops_track),
+ list(string)::in, list(string)::out, list(string)::out,
+ option_table(OptionType)::in, maybe_option_table_se(OptionType)::out,
+ set(OptionType)::out) is det.
+
:- pred init_option_table(
pred(OptionType, option_data)::in(pred(out, out) is nondet),
option_table(OptionType)::out) is det.
@@ -255,6 +276,59 @@
---> ok(option_table(OptionType))
; error(string).
+:- type maybe_option_table_se(OptionType)
+ ---> ok(option_table(OptionType))
+ ; error(option_error(OptionType)).
+
+:- type option_error(OptionType)
+ ---> unrecognized_option(string)
+ % An option that is not recognized appeared on the command line.
+ % The argument gives the option as it appeared on the command line.
+
+ ; option_error(OptionType, string, option_error_reason).
+ % An error occurred with a specific option. The first two arguments
+ % identify the option enumeration value and the string that appeared
+ % on the command line for that option respectively. The third
+ % argument describes the nature of the error with that option.
+
+:- type option_error_reason
+ ---> unknown_type
+ % No type for this option has been specified in the
+ % `option_default'/2 predicate.
+
+ ; requires_argument
+ % The option requires an argument but it occurred on the command
+ % line without one.
+
+ ; does_not_allow_argument(string)
+ % The option does not allow an argument but it was provided with
+ % one on the command line.
+ % The argument gives the contents of the argument position
+ % on the command line.
+
+ ; cannot_negate
+ % The option cannot be negated but its negated form appeared on
+ % the command line.
+
+ ; special_handler_failed
+ % The special option handler predicate for the option failed.
+
+ ; special_handler_missing
+ % A special option handler predicate was not provided for the option.
+
+ ; special_handler_error(string)
+ % The special option handler predicate for the option returned an
+ % error.
+ % The argument is a string describing the error.
+
+ ; requires_numeric_argument(string).
+ % The option requires a numeric argument but it occurred on the
+ % command line with a non-numeric argument.
+ % The third argument gives the argument as it appeared on the
+ % command line.
+
+:- func getopt.option_error_to_string(option_error(OptionType)) = string.
+
% The following three predicates search the option table for
% an option of the specified type; if it is not found, they
% report an error by calling error/1.
@@ -351,11 +425,46 @@ init_option_table_multi(OptionDefaultsPred, OptionTable) :-
), OptionDefaultsList),
map.from_assoc_list(OptionDefaultsList, OptionTable).
-getopt.process_options(OptionOps, Args0, NonOptionArgs, Result) :-
- getopt.process_options(OptionOps, Args0, _OptionArgs, NonOptionArgs,
+process_options(OptionOps, Args0, NonOptionArgs, Result) :-
+ process_options_se(OptionOps, Args0, NonOptionArgs, Result0),
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(Error),
+ Msg = option_error_to_string(Error),
+ Result = error(Msg)
+ ).
+
+process_options(OptionOps, Args0, OptionArgs, NonOptionArgs, Result) :-
+ process_options_se(OptionOps, Args0, OptionArgs, NonOptionArgs, Result0),
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(Error),
+ Msg = option_error_to_string(Error),
+ Result = error(Msg)
+ ).
+
+process_options_track(OptionOps, Args0, OptionArgs, NonOptionArgs,
+ OptionTable0, Result, OptionsSet) :-
+ process_options_track_se(OptionOps, Args0, OptionArgs, NonOptionArgs,
+ OptionTable0, Result0, OptionsSet),
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(Error),
+ Msg = option_error_to_string(Error),
+ Result = error(Msg)
+ ).
+
+getopt.process_options_se(OptionOps, Args0, NonOptionArgs, Result) :-
+ getopt.process_options_se(OptionOps, Args0, _OptionArgs, NonOptionArgs,
Result).
-getopt.process_options(OptionOps, Args0, OptionArgs, NonOptionArgs, Result) :-
+getopt.process_options_se(OptionOps, Args0, OptionArgs, NonOptionArgs, Result) :-
(
OptionOps = option_ops(Short, Long, Defaults),
MaybeSpecial = none,
@@ -378,7 +487,7 @@ getopt.process_options(OptionOps, Args0, OptionArgs, NonOptionArgs, Result) :-
[], RevOptionArgs, OptionTable0, Result, set.init, _OptionsSet),
OptionArgs = list.reverse(RevOptionArgs).
-getopt.process_options_track(OptionOps, Args0, OptionArgs, NonOptionArgs,
+getopt.process_options_track_se(OptionOps, Args0, OptionArgs, NonOptionArgs,
OptionTable0, Result, OptionsSet) :-
OptionOps = option_ops_track(Short, Long, Special),
Internal = option_ops_internal(Short, Long, track(Special)),
@@ -389,7 +498,7 @@ getopt.process_options_track(OptionOps, Args0, OptionArgs, NonOptionArgs,
:- pred getopt.process_arguments(list(string)::in, list(string)::out,
option_ops_internal(OptionType)::in(option_ops_internal), list(string)::in,
list(string)::out, option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
getopt.process_arguments([], [], _, OptionArgs, OptionArgs,
@@ -418,8 +527,8 @@ getopt.process_arguments([Option | Args0], Args, OptionOps,
Args = Args0
)
;
- ErrorMsg = "unrecognized option `" ++ Option ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option(Option),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
@@ -445,14 +554,14 @@ getopt.process_arguments([Option | Args0], Args, OptionOps,
[Option | OptionArgs0], OptionArgs,
OptionTable0, Result, !OptionsSet)
;
- ErrorMsg = "unknown type for option `" ++ Option ++ "'",
- Result = error(ErrorMsg),
+ Error = option_error(Flag, Option, unknown_type),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
;
- ErrorMsg = "unrecognized option `" ++ OptionName ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option(OptionName),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
@@ -477,8 +586,8 @@ getopt.process_arguments([Option | Args0], Args, OptionOps,
Args = Args0
)
;
- ErrorMsg = "unrecognized option `-" ++ ShortOptions ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option("-" ++ ShortOptions),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
@@ -515,7 +624,7 @@ getopt.process_arguments([Option | Args0], Args, OptionOps,
maybe(string)::in, list(string)::in, list(string)::out,
option_ops_internal(OptionType)::in(option_ops_internal), list(string)::in,
list(string)::out, option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
getopt.handle_long_option(Option, Flag, OptionData, MaybeOptionArg0,
@@ -548,18 +657,18 @@ getopt.handle_long_option(Option, Flag, OptionData, MaybeOptionArg0,
MissingArg = yes,
Args = Args0,
OptionArgs = OptionArgs1,
- ErrorMsg = "option `" ++ Option ++ "' needs an argument",
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, requires_argument),
+ Result = error(Error)
;
MissingArg = no,
(
getopt.need_arg(OptionData, no),
- MaybeOptionArg = yes(_)
+ MaybeOptionArg = yes(ArgVal)
->
Args = Args0,
OptionArgs = OptionArgs1,
- ErrorMsg = "option `" ++ Option ++ "' does not allow an argument",
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, does_not_allow_argument(ArgVal)),
+ Result = error(Error)
;
getopt.process_option(OptionData, Option, Flag, MaybeOptionArg,
OptionOps, OptionTable0, Result1, !OptionsSet),
@@ -580,7 +689,7 @@ getopt.handle_long_option(Option, Flag, OptionData, MaybeOptionArg0,
option_ops_internal(OptionType)::in(option_ops_internal), list(string)::in,
list(string)::out, list(string)::in, list(string)::out,
option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
getopt.handle_short_options([], _, Args, Args, OptionArgs, OptionArgs,
@@ -616,15 +725,15 @@ getopt.handle_short_options([Opt | Opts0], OptionOps, Args0, Args,
)
;
string.char_to_string(Opt, OptString),
- ErrorMsg = "unknown type for option `-" ++ OptString ++ "'",
- Result = error(ErrorMsg),
+ Error = option_error(Flag, "-" ++ OptString, unknown_type),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
;
string.char_to_string(Opt, OptString),
- ErrorMsg = "unrecognized option `-" ++ OptString ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option("-" ++ OptString),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
).
@@ -651,7 +760,7 @@ getopt.get_short_option_arg(Opts, Arg, Args0, Args,
:- pred getopt.process_option(option_data::in, string::in, OptionType::in,
maybe(string)::in, option_ops_internal(OptionType)::in(option_ops_internal),
option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
getopt.process_option(bool(_), _Option, Flag, MaybeArg, _OptionOps,
@@ -675,7 +784,7 @@ getopt.process_option(int(_), Option, Flag, MaybeArg, _OptionOps,
map.set(Flag, int(IntArg), !OptionTable),
Result = ok(!.OptionTable)
;
- getopt.numeric_argument(Option, Arg, Result)
+ getopt.numeric_argument(Flag, Option, Arg, Result)
)
;
MaybeArg = no,
@@ -701,7 +810,7 @@ getopt.process_option(maybe_int(_), Option, Flag, MaybeArg, _OptionOps,
map.set(Flag, maybe_int(yes(IntArg)), !OptionTable),
Result = ok(!.OptionTable)
;
- getopt.numeric_argument(Option, Arg, Result)
+ getopt.numeric_argument(Flag, Option, Arg, Result)
)
;
MaybeArg = no,
@@ -762,7 +871,7 @@ getopt.process_option(int_special, Option, Flag, MaybeArg, OptionOps,
getopt.process_special(Option, Flag, int(IntArg),
OptionOps, OptionTable0, Result, !OptionsSet)
;
- getopt.numeric_argument(Option, Arg, Result)
+ getopt.numeric_argument(Flag, Option, Arg, Result)
)
;
MaybeArg = no,
@@ -793,7 +902,7 @@ getopt.process_option(maybe_string_special, Option, Flag, MaybeArg, OptionOps,
:- pred process_negated_option(string::in, OptionType::in,
option_ops_internal(OptionType)::in(option_ops_internal),
- option_table(OptionType)::in, maybe_option_table(OptionType)::out,
+ option_table(OptionType)::in, maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
process_negated_option(Option, Flag, OptionOps, OptionTable0, Result,
@@ -830,45 +939,23 @@ process_negated_option(Option, Flag, OptionOps, OptionTable0, Result,
getopt.process_special(Option, Flag, maybe_string(no),
OptionOps, OptionTable0, Result, !OptionsSet)
;
- OptionData = int_special,
- string.append_list(["cannot negate option `", Option, "' --",
- "only boolean, maybe and accumulating options can be negated"],
- ErrorMsg),
- Result = error(ErrorMsg)
- ;
- OptionData = string_special,
- string.append_list(["cannot negate option `", Option, "' --",
- "only boolean, maybe and accumulating options can be negated"],
- ErrorMsg),
- Result = error(ErrorMsg)
- ;
- OptionData = int(_),
- string.append_list(["cannot negate option `", Option, "' --",
- "only boolean, maybe and accumulating options can be negated"],
- ErrorMsg),
- Result = error(ErrorMsg)
- ;
- OptionData = string(_),
- string.append_list(["cannot negate option `", Option, "' --",
- "only boolean, maybe and accumulating options can be negated"],
- ErrorMsg),
- Result = error(ErrorMsg)
- ;
- OptionData = special,
- string.append_list(["cannot negate option `", Option, "' --",
- "only boolean, maybe and accumulating options can be negated"],
- ErrorMsg),
- Result = error(ErrorMsg)
+ ( OptionData = int_special
+ ; OptionData = string_special
+ ; OptionData = int(_)
+ ; OptionData = string(_)
+ ; OptionData = special
+ ),
+ Error = option_error(Flag, Option, cannot_negate),
+ Result = error(Error)
)
;
- string.append_list(["unknown type for option `", Option, "'"],
- ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, unknown_type),
+ Result = error(Error)
).
:- pred getopt.process_special(string::in, OptionType::in, special_data::in,
option_ops_internal(OptionType)::in(option_ops_internal),
- option_table(OptionType)::in, maybe_option_table(OptionType)::out,
+ option_table(OptionType)::in, maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
getopt.process_special(Option, Flag, OptionData, OptionOps,
@@ -879,11 +966,18 @@ getopt.process_special(Option, Flag, OptionData, OptionOps,
(
Handler(Flag, OptionData, OptionTable0, Result0)
->
- Result = Result0
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(HandlerMsg),
+ Reason = special_handler_error(HandlerMsg),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
+ )
;
- string.append_list(["the handler of option `",
- Option, "' failed"], ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, special_handler_failed),
+ Result = error(Error)
)
;
MaybeHandler = track(TrackHandler),
@@ -892,17 +986,23 @@ getopt.process_special(Option, Flag, OptionData, OptionOps,
NewOptionsSet)
->
set.union(NewOptionsSet, !OptionsSet),
- Result = Result0
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(TrackHandlerMsg),
+ Reason = special_handler_error(TrackHandlerMsg),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
+ )
;
- string.append_list(["the handler of option `",
- Option, "' failed"], ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, special_handler_failed),
+ Result = error(Error)
)
;
MaybeHandler = none,
- string.append_list(["option `", Option, "' has no handler"],
- ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, special_handler_missing),
+ Result = error(Error)
).
%-----------------------------------------------------------------------------%
@@ -921,16 +1021,62 @@ getopt.need_arg(int_special, yes).
getopt.need_arg(string_special, yes).
getopt.need_arg(maybe_string_special, yes).
-:- pred getopt.numeric_argument(string::in, string::in,
- maybe_option_table(OptionType)::out) is det.
+:- pred getopt.numeric_argument(OptionType::in, string::in, string::in,
+ maybe_option_table_se(OptionType)::out) is det.
-getopt.numeric_argument(Option, Arg, Result) :-
- ErrorMsg = "option `" ++ Option ++ "'" ++
- "requires a numeric argument; `" ++ Arg ++ "' is not numeric",
- Result = error(ErrorMsg).
+getopt.numeric_argument(Flag, Option, Arg, Result) :-
+ Reason = requires_numeric_argument(Arg),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error).
%-----------------------------------------------------------------------------%
+option_error_to_string(Error) = String :-
+ (
+ Error = unrecognized_option(OptionName),
+ string.format("unrecognized option `%s'", [s(OptionName)], String)
+ ;
+ Error = option_error(_, OptionName, Reason),
+ (
+ Reason = unknown_type,
+ string.format("unknown type for option `%s'",
+ [s(OptionName)], String)
+ ;
+ Reason = requires_argument,
+ string.format("option `%s' needs an argument",
+ [s(OptionName)], String)
+ ;
+ Reason = does_not_allow_argument(_),
+ string.format("option `%s' does not allow an argument",
+ [s(OptionName)], String)
+ ;
+ Reason = cannot_negate,
+ string.format("cannot negate option `%s' -- " ++
+ "only boolean, maybe and accumulating options can be negated",
+ [s(OptionName)], String)
+ ;
+ Reason = special_handler_failed,
+ string.format("the handler of option `%s' failed",
+ [s(OptionName)], String)
+ ;
+ Reason = special_handler_missing,
+ string.format("option `%s' has no handler",
+ [s(OptionName)], String)
+ ;
+ Reason = special_handler_error(String)
+ ;
+ Reason = requires_numeric_argument(Arg),
+ string.format(
+ "option `%s' requires a numeric argument; `%s' is not numeric",
+ [s(OptionName), s(Arg)], String)
+ )
+ ).
+
+%-----------------------------------------------------------------------------%
+
+getopt.lookup_bool_option(OT, Opt) = B :-
+ getopt.lookup_bool_option(OT, Opt, B).
+
getopt.lookup_bool_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, bool(Val0)) ->
Val = Val0
@@ -938,6 +1084,9 @@ getopt.lookup_bool_option(OptionTable, Opt, Val) :-
error("Expected bool option and didn't get one.")
).
+getopt.lookup_int_option(OT, Opt) = N :-
+ getopt.lookup_int_option(OT, Opt, N).
+
getopt.lookup_int_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, int(Val0)) ->
Val = Val0
@@ -945,6 +1094,9 @@ getopt.lookup_int_option(OptionTable, Opt, Val) :-
error("Expected int option and didn't get one.")
).
+getopt.lookup_string_option(OT, Opt) = S :-
+ getopt.lookup_string_option(OT, Opt, S).
+
getopt.lookup_string_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, string(Val0)) ->
Val = Val0
@@ -952,6 +1104,9 @@ getopt.lookup_string_option(OptionTable, Opt, Val) :-
error("Expected string option and didn't get one.")
).
+getopt.lookup_maybe_int_option(OT, Opt) = MN :-
+ getopt.lookup_maybe_int_option(OT, Opt, MN).
+
getopt.lookup_maybe_int_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, maybe_int(Val0)) ->
Val = Val0
@@ -959,6 +1114,9 @@ getopt.lookup_maybe_int_option(OptionTable, Opt, Val) :-
error("Expected maybe_int option and didn't get one.")
).
+getopt.lookup_maybe_string_option(OT, Opt) = MS :-
+ getopt.lookup_maybe_string_option(OT, Opt, MS).
+
getopt.lookup_maybe_string_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, maybe_string(Val0)) ->
Val = Val0
@@ -966,6 +1124,9 @@ getopt.lookup_maybe_string_option(OptionTable, Opt, Val) :-
error("Expected maybe_string option and didn't get one.")
).
+getopt.lookup_accumulating_option(OT, Opt) = Ss :-
+ getopt.lookup_accumulating_option(OT, Opt, Ss).
+
getopt.lookup_accumulating_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, accumulating(Val0)) ->
Val = Val0
@@ -974,24 +1135,5 @@ getopt.lookup_accumulating_option(OptionTable, Opt, Val) :-
).
%-----------------------------------------------------------------------------%
+:- end_module getopt.
%-----------------------------------------------------------------------------%
-% Ralph Becket <rwab1 at cl.cam.ac.uk> 29/04/99
-% Functional forms added.
-
-getopt.lookup_bool_option(OT, Opt) = B :-
- getopt.lookup_bool_option(OT, Opt, B).
-
-getopt.lookup_int_option(OT, Opt) = N :-
- getopt.lookup_int_option(OT, Opt, N).
-
-getopt.lookup_string_option(OT, Opt) = S :-
- getopt.lookup_string_option(OT, Opt, S).
-
-getopt.lookup_maybe_int_option(OT, Opt) = MN :-
- getopt.lookup_maybe_int_option(OT, Opt, MN).
-
-getopt.lookup_maybe_string_option(OT, Opt) =MS :-
- getopt.lookup_maybe_string_option(OT, Opt, MS).
-
-getopt.lookup_accumulating_option(OT, Opt) =Ss :-
- getopt.lookup_accumulating_option(OT, Opt, Ss).
diff --git a/library/getopt_io.m b/library/getopt_io.m
index 84ea522..d4f54f7 100644
--- a/library/getopt_io.m
+++ b/library/getopt_io.m
@@ -153,6 +153,27 @@
option_table(OptionType)::in, maybe_option_table(OptionType)::out,
set(OptionType)::out, io::di, io::uo) is det.
+% Variants of the above that return structured errors.
+% These behave as the above versions except that any error values returned are
+% members of the option_error/1 type rather than strings.
+
+:- pred getopt_io.process_options_se(option_ops(OptionType)::in(option_ops),
+ list(string)::in, list(string)::out, maybe_option_table_se(OptionType)::out,
+ io::di, io::uo) is det.
+
+:- pred getopt_io.process_options_se(option_ops(OptionType)::in(option_ops),
+ list(string)::in, list(string)::out, list(string)::out,
+ maybe_option_table_se(OptionType)::out, io::di, io::uo) is det.
+
+% getopt_io.process_options_track_se(OptionOps, Args, OptionArgs,
+% NonOptionArgs, OptionTable0, Result, OptionsSet)
+
+:- pred getopt_io.process_options_track_se(
+ option_ops_track(OptionType)::in(option_ops_track),
+ list(string)::in, list(string)::out, list(string)::out,
+ option_table(OptionType)::in, maybe_option_table_se(OptionType)::out,
+ set(OptionType)::out, io::di, io::uo) is det.
+
:- pred init_option_table(
pred(OptionType, option_data)::in(pred(out, out) is nondet),
option_table(OptionType)::out) is det.
@@ -255,12 +276,82 @@
; string(string)
; maybe_string(maybe(string)).
-:- type option_table(OptionType) == map(OptionType, option_data).
+:- type option_table(OptionType) == map(OptionType, option_data).
:- type maybe_option_table(OptionType)
---> ok(option_table(OptionType))
; error(string).
+:- type maybe_option_table_se(OptionType)
+ ---> ok(option_table(OptionType))
+ ; error(option_error(OptionType)).
+
+:- type option_error(OptionType)
+ ---> unrecognized_option(string)
+ % An option that is not recognized appeared on the command line.
+ % The argument gives the option as it appeared on the command line.
+
+ ; option_error(OptionType, string, option_error_reason).
+ % An error occurred with a specific option. The first two arguments
+ % identify the option enumeration value and the string that appeared
+ % on the command line for that option respectively. The third
+ % argument describes the nature of the error with that option.
+
+:- type option_error_reason
+ ---> unknown_type
+ % No type for this option has been specified in the
+ % `option_default'/2 predicate.
+
+ ; requires_argument
+ % The option requires an argument but it occurred on the command
+ % line without one.
+
+ ; does_not_allow_argument(string)
+ % The option does not allow an argument but it was provided with
+ % one on the command line.
+ % The argument gives the contents of the argument position
+ % on the command line.
+
+ ; cannot_negate
+ % The option cannot be negated but its negated form appeared on
+ % the command line.
+
+ ; special_handler_failed
+ % The special option handler predicate for the option failed.
+
+ ; special_handler_missing
+ % A special option handler predicate was not provided for the option.
+
+ ; special_handler_error(string)
+ % The special option handler predicate for the option returned an
+ % error.
+ % The argument is a string describing the error.
+
+ ; requires_numeric_argument(string)
+ % The option requires a numeric argument but it occurred on the
+ % command line with a non-numeric argument.
+ % The third argument gives the argument as it appeared on the
+ % command line.
+
+ ; file_special_cannot_open(string, io.error)
+ % The option is a file_special option whose argument is the file
+ % named by the first argument.
+ % Attempting to open this file resulted in the I/O error given
+ % by the second argument.
+
+ ; file_special_cannot_read(string, io.error)
+ % The option is a file_special option whose argument is the file
+ % named by the first argument.
+ % Attempting to read from this file resulted in the I/O error given
+ % by the second argument.
+
+ ; file_special_contains_non_option_args(string).
+ % The option is a file_special option whose argument is the file
+ % named by the argument. This file contained some non-option
+ % arguments.
+
+:- func getopt_io.option_error_to_string(option_error(OptionType)) = string.
+
% The following three predicates search the option table for
% an option of the specified type; if it is not found, they
% report an error by calling error/1.
@@ -357,11 +448,47 @@ init_option_table_multi(OptionDefaultsPred, OptionTable) :-
), OptionDefaultsList),
map.from_assoc_list(OptionDefaultsList, OptionTable).
-getopt_io.process_options(OptionOps, Args0, NonOptionArgs, Result, !IO) :-
- getopt_io.process_options(OptionOps, Args0, _OptionArgs, NonOptionArgs,
+process_options(OptionOps, Args0, NonOptionArgs, Result, !IO) :-
+ process_options_se(OptionOps, Args0, NonOptionArgs, Result0, !IO),
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(Error),
+ Msg = option_error_to_string(Error),
+ Result = error(Msg)
+ ).
+
+process_options(OptionOps, Args0, OptionArgs, NonOptionArgs, Result, !IO) :-
+ process_options_se(OptionOps, Args0, OptionArgs, NonOptionArgs, Result0,
+ !IO),
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(Error),
+ Msg = option_error_to_string(Error),
+ Result = error(Msg)
+ ).
+
+process_options_track(OptionOps, Args0, OptionArgs, NonOptionArgs,
+ OptionTable0, Result, OptionsSet, !IO) :-
+ process_options_track_se(OptionOps, Args0, OptionArgs, NonOptionArgs,
+ OptionTable0, Result0, OptionsSet, !IO),
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(Error),
+ Msg = option_error_to_string(Error),
+ Result = error(Msg)
+ ).
+
+getopt_io.process_options_se(OptionOps, Args0, NonOptionArgs, Result, !IO) :-
+ getopt_io.process_options_se(OptionOps, Args0, _OptionArgs, NonOptionArgs,
Result, !IO).
-getopt_io.process_options(OptionOps, Args0, OptionArgs, NonOptionArgs, Result,
+getopt_io.process_options_se(OptionOps, Args0, OptionArgs, NonOptionArgs, Result,
!IO) :-
(
OptionOps = option_ops(Short, Long, Defaults),
@@ -385,7 +512,7 @@ getopt_io.process_options(OptionOps, Args0, OptionArgs, NonOptionArgs, Result,
[], RevOptionArgs, OptionTable0, Result, set.init, _OptionsSet, !IO),
OptionArgs = list.reverse(RevOptionArgs).
-getopt_io.process_options_track(OptionOps, Args0, OptionArgs, NonOptionArgs,
+getopt_io.process_options_track_se(OptionOps, Args0, OptionArgs, NonOptionArgs,
OptionTable0, Result, OptionsSet, !IO) :-
OptionOps = option_ops_track(Short, Long, Special),
Internal = option_ops_internal(Short, Long, track(Special)),
@@ -396,7 +523,7 @@ getopt_io.process_options_track(OptionOps, Args0, OptionArgs, NonOptionArgs,
:- pred getopt_io.process_arguments(list(string)::in, list(string)::out,
option_ops_internal(OptionType)::in(option_ops_internal), list(string)::in,
list(string)::out, option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out, io::di, io::uo) is det.
getopt_io.process_arguments([], [], _, OptionArgs, OptionArgs,
@@ -425,8 +552,8 @@ getopt_io.process_arguments([Option | Args0], Args, OptionOps,
Args = Args0
)
;
- ErrorMsg = "unrecognized option `-" ++ Option ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option(Option),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
@@ -452,14 +579,14 @@ getopt_io.process_arguments([Option | Args0], Args, OptionOps,
[Option | OptionArgs0], OptionArgs,
OptionTable0, Result, !OptionsSet, !IO)
;
- ErrorMsg = "unknown type for option `" ++ Option ++ "'",
- Result = error(ErrorMsg),
+ Error = option_error(Flag, Option, unknown_type),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
;
- ErrorMsg = "unrecognized option `" ++ OptionName ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option(OptionName),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
@@ -484,8 +611,8 @@ getopt_io.process_arguments([Option | Args0], Args, OptionOps,
Args = Args0
)
;
- ErrorMsg = "unrecognized option `-" ++ ShortOptions ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option("-" ++ ShortOptions),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
@@ -524,7 +651,7 @@ getopt_io.process_arguments([Option | Args0], Args, OptionOps,
maybe(string)::in, list(string)::in, list(string)::out,
option_ops_internal(OptionType)::in(option_ops_internal), list(string)::in,
list(string)::out, option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out, io::di, io::uo) is det.
getopt_io.handle_long_option(Option, Flag, OptionData, MaybeOptionArg0,
@@ -553,32 +680,36 @@ getopt_io.handle_long_option(Option, Flag, OptionData, MaybeOptionArg0,
OptionArgs1 = OptionArgs0,
MissingArg = no
),
- ( MissingArg = yes ->
- Args = Args0,
- OptionArgs = OptionArgs1,
- ErrorMsg = "option `" ++ Option ++ "' needs an argument",
- Result = error(ErrorMsg)
- ;
- getopt_io.need_arg(OptionData, no),
- MaybeOptionArg = yes(_)
- ->
+ (
+ MissingArg = yes,
Args = Args0,
OptionArgs = OptionArgs1,
- ErrorMsg = "option `" ++ Option ++ "' does not allow an argument",
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, requires_argument),
+ Result = error(Error)
;
- getopt_io.process_option(OptionData, Option, Flag, MaybeOptionArg,
- OptionOps, OptionTable0, Result1, !OptionsSet, !IO),
+ MissingArg = no,
(
- Result1 = ok(OptionTable1),
- getopt_io.process_arguments(Args1, Args, OptionOps,
- OptionArgs1, OptionArgs, OptionTable1, Result, !OptionsSet,
- !IO)
- ;
- Result1 = error(_),
- Result = Result1,
+ getopt_io.need_arg(OptionData, no),
+ MaybeOptionArg = yes(ArgVal)
+ ->
+ Args = Args0,
OptionArgs = OptionArgs1,
- Args = Args1
+ Error = option_error(Flag, Option, does_not_allow_argument(ArgVal)),
+ Result = error(Error)
+ ;
+ getopt_io.process_option(OptionData, Option, Flag, MaybeOptionArg,
+ OptionOps, OptionTable0, Result1, !OptionsSet, !IO),
+ (
+ Result1 = ok(OptionTable1),
+ getopt_io.process_arguments(Args1, Args, OptionOps,
+ OptionArgs1, OptionArgs, OptionTable1, Result, !OptionsSet,
+ !IO)
+ ;
+ Result1 = error(_),
+ Result = Result1,
+ OptionArgs = OptionArgs1,
+ Args = Args1
+ )
)
).
@@ -586,7 +717,7 @@ getopt_io.handle_long_option(Option, Flag, OptionData, MaybeOptionArg0,
option_ops_internal(OptionType)::in(option_ops_internal), list(string)::in,
list(string)::out, list(string)::in, list(string)::out,
option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out, io::di, io::uo) is det.
getopt_io.handle_short_options([], _, Args, Args, OptionArgs, OptionArgs,
@@ -623,15 +754,15 @@ getopt_io.handle_short_options([Opt | Opts0], OptionOps, Args0, Args,
)
;
string.char_to_string(Opt, OptString),
- ErrorMsg = "unknown type for option `-" ++ OptString ++ "'",
- Result = error(ErrorMsg),
+ Error = option_error(Flag, "-" ++ OptString, unknown_type),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
)
;
string.char_to_string(Opt, OptString),
- ErrorMsg = "unrecognized option `-" ++ OptString ++ "'",
- Result = error(ErrorMsg),
+ Error = unrecognized_option("-" ++ OptString),
+ Result = error(Error),
OptionArgs = OptionArgs0,
Args = Args0
).
@@ -658,7 +789,7 @@ getopt_io.get_short_option_arg(Opts, Arg, Args0, Args,
:- pred getopt_io.process_option(option_data::in, string::in, OptionType::in,
maybe(string)::in, option_ops_internal(OptionType)::in(option_ops_internal),
option_table(OptionType)::in,
- maybe_option_table(OptionType)::out,
+ maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out, io::di, io::uo) is det.
getopt_io.process_option(bool(_), _Option, Flag, MaybeArg, _OptionOps,
@@ -682,7 +813,7 @@ getopt_io.process_option(int(_), Option, Flag, MaybeArg, _OptionOps,
map.set(Flag, int(IntArg), !OptionTable),
Result = ok(!.OptionTable)
;
- getopt_io.numeric_argument(Option, Arg, Result)
+ getopt_io.numeric_argument(Flag, Option, Arg, Result)
)
;
MaybeArg = no,
@@ -708,7 +839,7 @@ getopt_io.process_option(maybe_int(_), Option, Flag, MaybeArg, _OptionOps,
map.set(Flag, maybe_int(yes(IntArg)), !OptionTable),
Result = ok(!.OptionTable)
;
- getopt_io.numeric_argument(Option, Arg, Result)
+ getopt_io.numeric_argument(Flag, Option, Arg, Result)
)
;
MaybeArg = no,
@@ -769,7 +900,7 @@ getopt_io.process_option(int_special, Option, Flag, MaybeArg, OptionOps,
getopt_io.process_special(Option, Flag, int(IntArg),
OptionOps, OptionTable0, Result, !OptionsSet)
;
- getopt_io.numeric_argument(Option, Arg, Result)
+ getopt_io.numeric_argument(Flag, Option, Arg, Result)
)
;
MaybeArg = no,
@@ -797,7 +928,7 @@ getopt_io.process_option(maybe_string_special, Option, Flag, MaybeArg,
error("maybe_string_special argument expected " ++
"in getopt_io.process_option")
).
-getopt_io.process_option(file_special, _Option, _Flag, MaybeArg, OptionOps,
+getopt_io.process_option(file_special, Option, Flag, MaybeArg, OptionOps,
OptionTable0, Result, !OptionsSet, !IO) :-
(
MaybeArg = yes(FileName),
@@ -815,19 +946,22 @@ getopt_io.process_option(file_special, _Option, _Flag, MaybeArg, OptionOps,
Result = Result0
;
Args = [_ | _],
- Result = error(FileName ++
- " contains non-option arguments")
+ Reason = file_special_contains_non_option_args(FileName),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
)
;
- ReadRes = error(_, Error),
- io.error_message(Error, Msg),
- Result = error("cannot read " ++ FileName ++ ": " ++ Msg)
+ ReadRes = error(_, IO_Error),
+ Reason = file_special_cannot_read(FileName, IO_Error),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
),
io.seen(!IO)
;
- SeeRes = error(Error),
- io.error_message(Error, Msg),
- Result = error("cannot open " ++ FileName ++ ": " ++ Msg)
+ SeeRes = error(IO_Error),
+ Reason = file_special_cannot_open(FileName, IO_Error),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
)
;
MaybeArg = no,
@@ -836,7 +970,7 @@ getopt_io.process_option(file_special, _Option, _Flag, MaybeArg, OptionOps,
:- pred process_negated_option(string::in, OptionType::in,
option_ops_internal(OptionType)::in(option_ops_internal),
- option_table(OptionType)::in, maybe_option_table(OptionType)::out,
+ option_table(OptionType)::in, maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
process_negated_option(Option, Flag, OptionOps, OptionTable0, Result,
@@ -873,45 +1007,24 @@ process_negated_option(Option, Flag, OptionOps, OptionTable0, Result,
getopt_io.process_special(Option, Flag, maybe_string(no),
OptionOps, OptionTable0, Result, !OptionsSet)
;
- OptionData = int_special,
- ErrorMsg = "cannot negate option `" ++ Option ++ "' --" ++
- "only boolean, maybe and accumulating options can be negated",
- Result = error(ErrorMsg)
- ;
- OptionData = string_special,
- ErrorMsg = "cannot negate option `" ++ Option ++ "' --" ++
- "only boolean, maybe and accumulating options can be negated",
- Result = error(ErrorMsg)
- ;
- OptionData = int(_),
- ErrorMsg = "cannot negate option `" ++ Option ++ "' --" ++
- "only boolean, maybe and accumulating options can be negated",
- Result = error(ErrorMsg)
- ;
- OptionData = string(_),
- ErrorMsg = "cannot negate option `" ++ Option ++ "' --" ++
- "only boolean, maybe and accumulating options can be negated",
- Result = error(ErrorMsg)
- ;
- OptionData = special,
- ErrorMsg = "cannot negate option `" ++ Option ++ "' --" ++
- "only boolean, maybe and accumulating options can be negated",
- Result = error(ErrorMsg)
- ;
- OptionData = file_special,
- ErrorMsg = "cannot negate option `" ++ Option ++ "' --" ++
- "only boolean, maybe and accumulating options can be negated",
- Result = error(ErrorMsg)
+ ( OptionData = int_special
+ ; OptionData = string_special
+ ; OptionData = int(_)
+ ; OptionData = string(_)
+ ; OptionData = special
+ ; OptionData = file_special
+ ),
+ Error = option_error(Flag, Option, cannot_negate),
+ Result = error(Error)
)
;
- string.append_list(["unknown type for option `", Option, "'"],
- ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, unknown_type),
+ Result = error(Error)
).
:- pred getopt_io.process_special(string::in, OptionType::in, special_data::in,
option_ops_internal(OptionType)::in(option_ops_internal),
- option_table(OptionType)::in, maybe_option_table(OptionType)::out,
+ option_table(OptionType)::in, maybe_option_table_se(OptionType)::out,
set(OptionType)::in, set(OptionType)::out) is det.
getopt_io.process_special(Option, Flag, OptionData, OptionOps,
@@ -922,11 +1035,18 @@ getopt_io.process_special(Option, Flag, OptionData, OptionOps,
(
Handler(Flag, OptionData, OptionTable0, Result0)
->
- Result = Result0
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(HandlerMsg),
+ Reason = special_handler_error(HandlerMsg),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
+ )
;
- string.append_list(["the handler of option `",
- Option, "' failed"], ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, special_handler_failed),
+ Result = error(Error)
)
;
MaybeHandler = track(TrackHandler),
@@ -935,16 +1055,23 @@ getopt_io.process_special(Option, Flag, OptionData, OptionOps,
NewOptionsSet)
->
set.union(NewOptionsSet, !OptionsSet),
- Result = Result0
+ (
+ Result0 = ok(OptionTable),
+ Result = ok(OptionTable)
+ ;
+ Result0 = error(TrackHandlerMsg),
+ Reason = special_handler_error(TrackHandlerMsg),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error)
+ )
;
- string.append_list(["the handler of option `",
- Option, "' failed"], ErrorMsg),
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, special_handler_failed),
+ Result = error(Error)
)
;
MaybeHandler = none,
- ErrorMsg = "option `" ++ Option ++ "' has no handler",
- Result = error(ErrorMsg)
+ Error = option_error(Flag, Option, special_handler_missing),
+ Result = error(Error)
).
%-----------------------------------------------------------------------------%
@@ -964,16 +1091,74 @@ getopt_io.need_arg(string_special, yes).
getopt_io.need_arg(maybe_string_special, yes).
getopt_io.need_arg(file_special, yes).
-:- pred getopt_io.numeric_argument(string::in, string::in,
- maybe_option_table(OptionType)::out) is det.
+:- pred getopt_io.numeric_argument(OptionType::in, string::in, string::in,
+ maybe_option_table_se(OptionType)::out) is det.
-getopt_io.numeric_argument(Option, Arg, Result) :-
- ErrorMsg = "option `" ++ Option ++
- "' requires a numeric argument; `" ++ Arg ++ "' is not numeric",
- Result = error(ErrorMsg).
+getopt_io.numeric_argument(Flag, Option, Arg, Result) :-
+ Reason = requires_numeric_argument(Arg),
+ Error = option_error(Flag, Option, Reason),
+ Result = error(Error).
%-----------------------------------------------------------------------------%
+option_error_to_string(Error) = String :-
+ (
+ Error = unrecognized_option(OptionName),
+ string.format("unrecognized option `%s'", [s(OptionName)], String)
+ ;
+ Error = option_error(_, OptionName, Reason),
+ (
+ Reason = unknown_type,
+ string.format("unknown type for option `%s'",
+ [s(OptionName)], String)
+ ;
+ Reason = requires_argument,
+ string.format("option `%s' needs an argument",
+ [s(OptionName)], String)
+ ;
+ Reason = does_not_allow_argument(_),
+ string.format("option `%s' does not allow an argument",
+ [s(OptionName)], String)
+ ;
+ Reason = cannot_negate,
+ string.format("cannot negate option `%s' -- " ++
+ "only boolean, maybe and accumulating options can be negated",
+ [s(OptionName)], String)
+ ;
+ Reason = special_handler_failed,
+ string.format("the handler of option `%s' failed",
+ [s(OptionName)], String)
+ ;
+ Reason = special_handler_missing,
+ string.format("option `%s' has no handler",
+ [s(OptionName)], String)
+ ;
+ Reason = special_handler_error(String)
+ ;
+ Reason = requires_numeric_argument(Arg),
+ string.format(
+ "option `%s' requires a numeric argument; `%s' is not numeric",
+ [s(OptionName), s(Arg)], String)
+ ;
+ Reason = file_special_cannot_open(FileName, IO_Error),
+ io.error_message(IO_Error, Msg),
+ string.format("cannot open %s: %s", [s(FileName), s(Msg)], String)
+ ;
+ Reason = file_special_cannot_read(FileName, IO_Error),
+ io.error_message(IO_Error, Msg),
+ string.format("cannot read %s: %s", [s(FileName), s(Msg)], String)
+ ;
+ Reason = file_special_contains_non_option_args(FileName),
+ string.format("%s contains non-option arguments",
+ [s(FileName)], String)
+ )
+ ).
+
+%-----------------------------------------------------------------------------%
+
+getopt_io.lookup_bool_option(OT, Opt) = B :-
+ getopt_io.lookup_bool_option(OT, Opt, B).
+
getopt_io.lookup_bool_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, bool(Val0)) ->
Val = Val0
@@ -981,6 +1166,9 @@ getopt_io.lookup_bool_option(OptionTable, Opt, Val) :-
error("Expected bool option and didn't get one.")
).
+getopt_io.lookup_int_option(OT, Opt) = N :-
+ getopt_io.lookup_int_option(OT, Opt, N).
+
getopt_io.lookup_int_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, int(Val0)) ->
Val = Val0
@@ -988,6 +1176,9 @@ getopt_io.lookup_int_option(OptionTable, Opt, Val) :-
error("Expected int option and didn't get one.")
).
+getopt_io.lookup_string_option(OT, Opt) = S :-
+ getopt_io.lookup_string_option(OT, Opt, S).
+
getopt_io.lookup_string_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, string(Val0)) ->
Val = Val0
@@ -995,6 +1186,9 @@ getopt_io.lookup_string_option(OptionTable, Opt, Val) :-
error("Expected string option and didn't get one.")
).
+getopt_io.lookup_maybe_int_option(OT, Opt) = MN :-
+ getopt_io.lookup_maybe_int_option(OT, Opt, MN).
+
getopt_io.lookup_maybe_int_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, maybe_int(Val0)) ->
Val = Val0
@@ -1002,6 +1196,9 @@ getopt_io.lookup_maybe_int_option(OptionTable, Opt, Val) :-
error("Expected maybe_int option and didn't get one.")
).
+getopt_io.lookup_maybe_string_option(OT, Opt) = MS :-
+ getopt_io.lookup_maybe_string_option(OT, Opt, MS).
+
getopt_io.lookup_maybe_string_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, maybe_string(Val0)) ->
Val = Val0
@@ -1009,6 +1206,9 @@ getopt_io.lookup_maybe_string_option(OptionTable, Opt, Val) :-
error("Expected maybe_string option and didn't get one.")
).
+getopt_io.lookup_accumulating_option(OT, Opt) = Ss :-
+ getopt_io.lookup_accumulating_option(OT, Opt, Ss).
+
getopt_io.lookup_accumulating_option(OptionTable, Opt, Val) :-
( map.lookup(OptionTable, Opt, accumulating(Val0)) ->
Val = Val0
@@ -1017,24 +1217,5 @@ getopt_io.lookup_accumulating_option(OptionTable, Opt, Val) :-
).
%-----------------------------------------------------------------------------%
+:- end_module getopt_io.
%-----------------------------------------------------------------------------%
-% Ralph Becket <rwab1 at cl.cam.ac.uk> 29/04/99
-% Functional forms added.
-
-getopt_io.lookup_bool_option(OT, Opt) = B :-
- getopt_io.lookup_bool_option(OT, Opt, B).
-
-getopt_io.lookup_int_option(OT, Opt) = N :-
- getopt_io.lookup_int_option(OT, Opt, N).
-
-getopt_io.lookup_string_option(OT, Opt) = S :-
- getopt_io.lookup_string_option(OT, Opt, S).
-
-getopt_io.lookup_maybe_int_option(OT, Opt) = MN :-
- getopt_io.lookup_maybe_int_option(OT, Opt, MN).
-
-getopt_io.lookup_maybe_string_option(OT, Opt) =MS :-
- getopt_io.lookup_maybe_string_option(OT, Opt, MS).
-
-getopt_io.lookup_accumulating_option(OT, Opt) =Ss :-
- getopt_io.lookup_accumulating_option(OT, Opt, Ss).
More information about the reviews
mailing list