Expose getopt:tokenize/1 and command-line literals

This commit is contained in:
Juan Jose Comellas
2012-07-20 11:00:25 -03:00
parent 08931e2394
commit f55ef18bab
3 changed files with 70 additions and 26 deletions
+24 -25
View File
@@ -11,8 +11,7 @@
-module(getopt).
-author('juanjo@comellas.org').
-export([parse/2, usage/2, usage/3, usage/4]).
-export([tokenize_cmdline/1]).
-export([parse/2, usage/2, usage/3, usage/4, tokenize/1]).
-export_type([arg_type/0,
arg_value/0,
@@ -67,7 +66,7 @@ parse(OptSpecList, CmdLine) ->
try
Args = if
is_integer(hd(CmdLine)) ->
tokenize_cmdline(CmdLine);
tokenize(CmdLine);
true ->
CmdLine
end,
@@ -612,12 +611,12 @@ add_option_help(_Opt, _Prefix, Acc) ->
%% The function also supports the expansion of environment variables in
%% both the Unix (${VAR}; $VAR) and Windows (%VAR%) formats. It does NOT
%% support wildcard expansion of paths.
-spec tokenize_cmdline(CmdLine :: string()) -> [string()].
tokenize_cmdline(CmdLine) ->
tokenize_cmdline(CmdLine, [], []).
-spec tokenize(CmdLine :: string()) -> [string()].
tokenize(CmdLine) ->
tokenize(CmdLine, [], []).
-spec tokenize_cmdline(CmdLine :: string(), Acc :: [string()], ArgAcc :: string()) -> [string()].
tokenize_cmdline([Sep | Tail], Acc, ArgAcc) when Sep =:= $\s; Sep =:= $\t; Sep =:= $\n ->
-spec tokenize(CmdLine :: string(), Acc :: [string()], ArgAcc :: string()) -> [string()].
tokenize([Sep | Tail], Acc, ArgAcc) when Sep =:= $\s; Sep =:= $\t; Sep =:= $\n ->
NewAcc = case ArgAcc of
[_ | _] ->
%% Found separator: add to the list of arguments.
@@ -626,39 +625,39 @@ tokenize_cmdline([Sep | Tail], Acc, ArgAcc) when Sep =:= $\s; Sep =:= $\t; Sep =
%% Found separator with no accumulated argument; discard it.
Acc
end,
tokenize_cmdline(Tail, NewAcc, []);
tokenize_cmdline([QuotationMark | Tail], Acc, ArgAcc) when QuotationMark =:= $"; QuotationMark =:= $' ->
tokenize(Tail, NewAcc, []);
tokenize([QuotationMark | Tail], Acc, ArgAcc) when QuotationMark =:= $"; QuotationMark =:= $' ->
%% Quoted argument (might contain spaces, tabs, etc.)
tokenize_quoted_arg(QuotationMark, Tail, Acc, ArgAcc);
tokenize_cmdline([Char | _Tail] = CmdLine, Acc, ArgAcc) when Char =:= $$; Char =:= $% ->
tokenize([Char | _Tail] = CmdLine, Acc, ArgAcc) when Char =:= $$; Char =:= $% ->
%% Unix and Windows environment variable expansion: ${VAR}; $VAR; %VAR%
{NewCmdLine, Var} = expand_env_var(CmdLine),
tokenize_cmdline(NewCmdLine, Acc, lists:reverse(Var, ArgAcc));
tokenize_cmdline([$\\, Char | Tail], Acc, ArgAcc) ->
tokenize(NewCmdLine, Acc, lists:reverse(Var, ArgAcc));
tokenize([$\\, Char | Tail], Acc, ArgAcc) ->
%% Escaped char.
tokenize_cmdline(Tail, Acc, [Char | ArgAcc]);
tokenize_cmdline([Char | Tail], Acc, ArgAcc) ->
tokenize_cmdline(Tail, Acc, [Char | ArgAcc]);
tokenize_cmdline([], Acc, []) ->
tokenize(Tail, Acc, [Char | ArgAcc]);
tokenize([Char | Tail], Acc, ArgAcc) ->
tokenize(Tail, Acc, [Char | ArgAcc]);
tokenize([], Acc, []) ->
lists:reverse(Acc);
tokenize_cmdline([], Acc, ArgAcc) ->
tokenize([], Acc, ArgAcc) ->
lists:reverse([lists:reverse(ArgAcc) | Acc]).
-spec tokenize_quoted_arg(QuotationMark :: char(), CmdLine :: string(), Acc :: [string()], ArgAcc :: string()) -> [string()].
tokenize_quoted_arg(QuotationMark, [QuotationMark | Tail], Acc, ArgAcc) ->
%% End of quoted argument
tokenize_cmdline(Tail, Acc, ArgAcc);
tokenize_quoted_arg($" = QuotationMark, [Char | _Tail] = CmdLine, Acc, ArgAcc) when Char =:= $$; Char =:= $% ->
%% Unix and Windows environment variable expansion: ${VAR}; $VAR; %VAR%
{NewCmdLine, Var} = expand_env_var(CmdLine),
tokenize_quoted_arg(QuotationMark, NewCmdLine, Acc, lists:reverse(Var, ArgAcc));
tokenize(Tail, Acc, ArgAcc);
tokenize_quoted_arg(QuotationMark, [$\\, Char | Tail], Acc, ArgAcc) ->
%% Escaped char.
tokenize_quoted_arg(QuotationMark, Tail, Acc, [Char | ArgAcc]);
tokenize_quoted_arg($" = QuotationMark, [Char | _Tail] = CmdLine, Acc, ArgAcc) when Char =:= $$; Char =:= $% ->
%% Unix and Windows environment variable expansion (only for double-quoted arguments): ${VAR}; $VAR; %VAR%
{NewCmdLine, Var} = expand_env_var(CmdLine),
tokenize_quoted_arg(QuotationMark, NewCmdLine, Acc, lists:reverse(Var, ArgAcc));
tokenize_quoted_arg(QuotationMark, [Char | Tail], Acc, ArgAcc) ->
tokenize_quoted_arg(QuotationMark, Tail, Acc, [Char | ArgAcc]);
tokenize_quoted_arg(_QuotationMark, CmdLine, Acc, ArgAcc) ->
tokenize_cmdline(CmdLine, Acc, ArgAcc).
tokenize(CmdLine, Acc, ArgAcc).
-spec expand_env_var(CmdLine :: string()) -> string().
@@ -695,7 +694,7 @@ expand_env_var(Prefix, CmdLine, Acc) ->
-spec get_env_var(Prefix :: string(), Suffix :: string(), Acc :: string()) -> string().
get_env_var(Prefix, Suffix, [_ | _] = Acc) ->
Name = lists:reverse(Acc),
%% Only expand valid variables.
%% Only expand valid/existing variables.
case os:getenv(Name) of
false -> Prefix ++ Name ++ Suffix;
Value -> Value