Add support for arguments assigned to options with an equal ('=')
character within the option string. e.g. "--port=1000".
This commit is contained in:
parent
0be58dc525
commit
d26cb9df09
@ -56,7 +56,7 @@ The fields of the record are:
|
|||||||
- ``Short``: character for the short option (e.g. $i for -i).
|
- ``Short``: character for the short option (e.g. $i for -i).
|
||||||
- ``Long``: string for the long option (e.g. "info" for --info).
|
- ``Long``: string for the long option (e.g. "info" for --info).
|
||||||
- ``ArgSpec``: data type and optional default value the argument will be converted to.
|
- ``ArgSpec``: data type and optional default value the argument will be converted to.
|
||||||
- ``Help``: help message that is shown for the option when usage/2 is called.
|
- ``Help``: help message that is shown for the option when ``usage/2`` is called.
|
||||||
|
|
||||||
The second parameter holds the list of arguments as passed to the ``main/1``
|
The second parameter holds the list of arguments as passed to the ``main/1``
|
||||||
function in escripts. e.g.
|
function in escripts. e.g.
|
||||||
@ -85,11 +85,11 @@ e.g. For a program named ``ex.escript`` with the following option specifications
|
|||||||
|
|
||||||
And this command line:
|
And this command line:
|
||||||
|
|
||||||
Args = "-h myhost --port 1000 -x myfile.txt dummy1 dummy2"
|
Args = "-h myhost --port=1000 -x myfile.txt dummy1 dummy2"
|
||||||
|
|
||||||
Which could also be passed in the format the ``main/1`` function receives the arguments in escripts:
|
Which could also be passed in the format the ``main/1`` function receives the arguments in escripts:
|
||||||
|
|
||||||
Args = ["-h", "myhost", "--port", "1000", "-x", "myfile.txt", "dummy1", "dummy2"].
|
Args = ["-h", "myhost", "--port=1000", "-x", "myfile.txt", "dummy1", "dummy2"].
|
||||||
|
|
||||||
The call to ``getopt:parse/2``:
|
The call to ``getopt:parse/2``:
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ Also, the call to ``getopt:usage/2``:
|
|||||||
|
|
||||||
Will show (on *stdout*):
|
Will show (on *stdout*):
|
||||||
|
|
||||||
Usage: ex.escript [-h <host>] [-p <port>] [--dbname <dbname>] [-x] <file>
|
Usage: ex1 [-h <host>] [-p <port>] [--dbname <dbname>] [-x] <file>
|
||||||
|
|
||||||
-h, --host Database server host
|
-h, --host Database server host
|
||||||
-p, --port Database server port
|
-p, --port Database server port
|
||||||
|
@ -72,7 +72,15 @@ parse(OptSpecList, CmdLine) ->
|
|||||||
{ok, {[option()], [string()]}} | {error, {Reason :: atom(), Data:: any()}}.
|
{ok, {[option()], [string()]}} | {error, {Reason :: atom(), Data:: any()}}.
|
||||||
%% Process long options.
|
%% Process long options.
|
||||||
parse(OptSpecList, OptAcc, ArgAcc, ArgPos, [[$-, $- | LongName] = OptStr | Tail]) ->
|
parse(OptSpecList, OptAcc, ArgAcc, ArgPos, [[$-, $- | LongName] = OptStr | Tail]) ->
|
||||||
{Option, Tail1} = get_option(OptSpecList, OptStr, LongName, ?OPT_LONG, Tail),
|
{Option, Tail1} =
|
||||||
|
case string:tokens(LongName, "=") of
|
||||||
|
[_LongName1] ->
|
||||||
|
get_option(OptSpecList, OptStr, LongName, ?OPT_LONG, Tail);
|
||||||
|
[LongName1, Arg] ->
|
||||||
|
{get_option_embedded_arg(OptSpecList, OptStr, LongName1, Arg), Tail};
|
||||||
|
_ ->
|
||||||
|
throw({error, {invalid_option_arg, OptStr}})
|
||||||
|
end,
|
||||||
parse(OptSpecList, [Option | OptAcc], ArgAcc, ArgPos, Tail1);
|
parse(OptSpecList, [Option | OptAcc], ArgAcc, ArgPos, Tail1);
|
||||||
%% Process short options.
|
%% Process short options.
|
||||||
parse(OptSpecList, OptAcc, ArgAcc, ArgPos, [[$-, ShortName] = OptStr | Tail]) ->
|
parse(OptSpecList, OptAcc, ArgAcc, ArgPos, [[$-, ShortName] = OptStr | Tail]) ->
|
||||||
@ -122,6 +130,23 @@ get_option(OptSpecList, OptStr, OptName, FieldPos, Tail) ->
|
|||||||
throw({error, {invalid_option, OptStr}})
|
throw({error, {invalid_option, OptStr}})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
-spec get_option_embedded_arg([option_spec()], string(), string(), string()) -> option().
|
||||||
|
%% @doc Retrieve the specification corresponding to an option matching a string
|
||||||
|
%% received on the command line that had its argument assigned within the
|
||||||
|
%% same string (e.g. "--verbose=true").
|
||||||
|
get_option_embedded_arg(OptSpecList, OptStr, OptName, Arg) ->
|
||||||
|
case lists:keysearch(OptName, ?OPT_LONG, OptSpecList) of
|
||||||
|
{value, {_Name, _Short, _Long, ArgSpec, _Help} = OptSpec} ->
|
||||||
|
case ArgSpec of
|
||||||
|
undefined ->
|
||||||
|
throw({error, {invalid_option_arg, OptStr}});
|
||||||
|
_ ->
|
||||||
|
convert_option_arg(OptSpec, Arg)
|
||||||
|
end;
|
||||||
|
false ->
|
||||||
|
throw({error, {invalid_option, OptStr}})
|
||||||
|
end.
|
||||||
|
|
||||||
-spec get_option_no_arg([option_spec()], string(), string() | char(), integer()) -> option().
|
-spec get_option_no_arg([option_spec()], string(), string() | char(), integer()) -> option().
|
||||||
%% @doc Retrieve the specification corresponding to an option that has no
|
%% @doc Retrieve the specification corresponding to an option that has no
|
||||||
%% argument and matches a string received on the command line.
|
%% argument and matches a string received on the command line.
|
||||||
@ -195,7 +220,8 @@ to_type(boolean, Arg) ->
|
|||||||
LowerArg = string:to_lower(Arg),
|
LowerArg = string:to_lower(Arg),
|
||||||
(LowerArg =:= "true") orelse (LowerArg =:= "t") orelse
|
(LowerArg =:= "true") orelse (LowerArg =:= "t") orelse
|
||||||
(LowerArg =:= "yes") orelse (LowerArg =:= "y") orelse
|
(LowerArg =:= "yes") orelse (LowerArg =:= "y") orelse
|
||||||
(LowerArg =:= "on") orelse (LowerArg =:= "enabled");
|
(LowerArg =:= "on") orelse (LowerArg =:= "enabled") orelse
|
||||||
|
(LowerArg =:= "1");
|
||||||
to_type(_Type, Arg) ->
|
to_type(_Type, Arg) ->
|
||||||
Arg.
|
Arg.
|
||||||
|
|
||||||
|
@ -126,8 +126,13 @@ parse_1_test_() ->
|
|||||||
%% Options with only the long form
|
%% Options with only the long form
|
||||||
{?HELP(Long), ?_assertMatch({ok, {[long], []}}, parse([Long], ["--long"]))},
|
{?HELP(Long), ?_assertMatch({ok, {[long], []}}, parse([Long], ["--long"]))},
|
||||||
{?HELP(LongArg), ?_assertMatch({ok, {[{long_arg, "value"}], []}}, parse([LongArg], ["--long-arg", "value"]))},
|
{?HELP(LongArg), ?_assertMatch({ok, {[{long_arg, "value"}], []}}, parse([LongArg], ["--long-arg", "value"]))},
|
||||||
|
{?HELP(LongArg), ?_assertMatch({ok, {[{long_arg, "value"}], []}}, parse([LongArg], ["--long-arg=value"]))},
|
||||||
{?HELP(LongDefArg), ?_assertMatch({ok, {[{long_def_arg, "default-long"}], []}}, parse([LongDefArg], []))},
|
{?HELP(LongDefArg), ?_assertMatch({ok, {[{long_def_arg, "default-long"}], []}}, parse([LongDefArg], []))},
|
||||||
{?HELP(LongInt), ?_assertMatch({ok, {[{long_int, 100}], []}}, parse([LongInt], ["--long-int", "100"]))},
|
{?HELP(LongInt), ?_assertMatch({ok, {[{long_int, 100}], []}}, parse([LongInt], ["--long-int", "100"]))},
|
||||||
|
{?HELP(LongInt), ?_assertMatch({ok, {[{long_int, 100}], []}}, parse([LongInt], ["--long-int=100"]))},
|
||||||
|
%% Options with only the long form (expected failures)
|
||||||
|
{?HELP(LongArg) ++ " (XFAIL)",
|
||||||
|
?_assertEqual({error, {invalid_option_arg, "--long-arg=value=1"}}, parse([LongArg], ["--long-arg=value=1"]))},
|
||||||
{"Long form option and arguments",
|
{"Long form option and arguments",
|
||||||
?_assertMatch({ok, {[long], ["arg1", "arg2"]}}, parse([Long], ["--long", "arg1", "arg2"]))},
|
?_assertMatch({ok, {[long], ["arg1", "arg2"]}}, parse([Long], ["--long", "arg1", "arg2"]))},
|
||||||
{"Long form option and arguments (unsorted)",
|
{"Long form option and arguments (unsorted)",
|
||||||
@ -137,9 +142,11 @@ parse_1_test_() ->
|
|||||||
{?HELP(ShortLong), ?_assertMatch({ok, {[short_long], []}}, parse([ShortLong], ["--short-long"]))},
|
{?HELP(ShortLong), ?_assertMatch({ok, {[short_long], []}}, parse([ShortLong], ["--short-long"]))},
|
||||||
{?HELP(ShortLongArg), ?_assertEqual({ok, {[{short_long_arg, "value"}], []}}, parse([ShortLongArg], [[$-, ?SHORT(ShortLongArg)], "value"]))},
|
{?HELP(ShortLongArg), ?_assertEqual({ok, {[{short_long_arg, "value"}], []}}, parse([ShortLongArg], [[$-, ?SHORT(ShortLongArg)], "value"]))},
|
||||||
{?HELP(ShortLongArg), ?_assertMatch({ok, {[{short_long_arg, "value"}], []}}, parse([ShortLongArg], ["--short-long-arg", "value"]))},
|
{?HELP(ShortLongArg), ?_assertMatch({ok, {[{short_long_arg, "value"}], []}}, parse([ShortLongArg], ["--short-long-arg", "value"]))},
|
||||||
|
{?HELP(ShortLongArg), ?_assertMatch({ok, {[{short_long_arg, "value"}], []}}, parse([ShortLongArg], ["--short-long-arg=value"]))},
|
||||||
{?HELP(ShortLongDefArg), ?_assertMatch({ok, {[{short_long_def_arg, "default-short-long"}], []}}, parse([ShortLongDefArg], []))},
|
{?HELP(ShortLongDefArg), ?_assertMatch({ok, {[{short_long_def_arg, "default-short-long"}], []}}, parse([ShortLongDefArg], []))},
|
||||||
{?HELP(ShortLongInt), ?_assertEqual({ok, {[{short_long_int, 1234}], []}}, parse([ShortLongInt], [[$-, ?SHORT(ShortLongInt)], "1234"]))},
|
{?HELP(ShortLongInt), ?_assertEqual({ok, {[{short_long_int, 1234}], []}}, parse([ShortLongInt], [[$-, ?SHORT(ShortLongInt)], "1234"]))},
|
||||||
{?HELP(ShortLongInt), ?_assertMatch({ok, {[{short_long_int, 1234}], []}}, parse([ShortLongInt], ["--short-long-int", "1234"]))},
|
{?HELP(ShortLongInt), ?_assertMatch({ok, {[{short_long_int, 1234}], []}}, parse([ShortLongInt], ["--short-long-int", "1234"]))},
|
||||||
|
{?HELP(ShortLongInt), ?_assertMatch({ok, {[{short_long_int, 1234}], []}}, parse([ShortLongInt], ["--short-long-int=1234"]))},
|
||||||
%% Non-option arguments
|
%% Non-option arguments
|
||||||
{?HELP(NonOptArg), ?_assertMatch({ok, {[{non_opt_arg, "value"}], []}}, parse([NonOptArg], ["value"]))},
|
{?HELP(NonOptArg), ?_assertMatch({ok, {[{non_opt_arg, "value"}], []}}, parse([NonOptArg], ["value"]))},
|
||||||
{?HELP(NonOptInt), ?_assertMatch({ok, {[{non_opt_int, 1234}], []}}, parse([NonOptInt], ["1234"]))},
|
{?HELP(NonOptInt), ?_assertMatch({ok, {[{non_opt_int, 1234}], []}}, parse([NonOptInt], ["1234"]))},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user