Codebase list erlang-getopt / 8954556
Merge tag 'upstream/1.0.1' Nobuhiro Iwamatsu 6 years ago
7 changed file(s) with 177 addition(s) and 124 deletion(s). Raw diff Collapse all Expand all
00 APPLICATION := getopt
11
2 REBAR=$(shell which rebar || echo ./rebar)
3 ERL := erl
4 EPATH := -pa ebin
5
6 DIALYZER=dialyzer
7 DIALYZER_OPTS=-Wno_return -Wrace_conditions -Wunderspecs -Wno_undefined_callbacks --fullpath
8
9 .PHONY: all clean compile console dialyze doc test
2 .PHONY: all clean compile dialyzer edoc shell test
103
114 all: compile
125
136 clean:
14 @$(REBAR) clean
7 @rebar3 clean
158
169 compile:
17 @$(REBAR) compile
10 @rebar3 compile
1811
19 console:
20 $(ERL) -sname $(APPLICATION) $(EPATH)
12 dialyzer: compile
13 @rebar3 dialyzer
2114
22 dialyze: compile
23 @$(DIALYZER) $(DIALYZER_OPTS) -r ./
15 edoc:
16 @rebar3 edoc
2417
25 doc:
26 @$(REBAR) doc
18 shell:
19 @rebar3 shell
2720
2821 test:
29 @erl -make
30 @$(ERL) -sname $(APPLICATION) $(EPATH) -noinput -s getopt_test test -s init stop
22 @rebar3 eunit
3123
77 ------------
88
99 You should only need a somewhat recent version of Erlang/OTP. The module has
10 been tested with Erlang R13B, R14B, R15B and R16B.
11
12 You also need a recent version of [rebar](http://github.com/basho/rebar) in
13 the system path. If you're going to run the unit tests you need the latest
14 version of rebar to make sure that the latest version of *getopt* is being
15 used. rebar already includes a compiled copy of the ``getopt`` module in its
16 own binary file and will give precedence to its own modules over the ones in
17 the project.
18
10 been tested with all versions of Erlang starting with R13B and ending with 20.
11
12 You also need a recent version of [rebar3](http://www.rebar3.org/) in
13 the system path.
1914
2015 Installation
2116 ------------
2217
23 To compile the module you simply run ``make``.
24
25 To run the unit tests run ``make test``.
26
27 To run the example module run ``make example``.
28
29 To build the (very) limited documentation run ``make doc``.
30
31 After the module is compiled with ``make``, insert getopt into the Erlang lib directory (e.g. by soft link or copying).
32
18 To compile the module you simply run `rebar3 compile`.
19
20 To run the unit tests run `rebar3 eunit`.
21
22 To build the (very) limited documentation run `rebar edoc`.
23
24 To use getopt in your project you can just add it as a dependency in your
25 `rebar.config` file in the following way:
3326 ```sh
34 ln -s . /usr/local/lib/erlang/lib/getopt-0.8.2
27 {deps,
28 [
29 {getopt, "1.0.1"}
30 ]
31 }
3532 ```
3633
3734
3835 Usage
3936 -----
4037
41 The *getopt* module provides four functions:
42
43 ``` erlang
38 The `getopt` module provides four functions:
39
40 ```erlang
4441 parse([{Name, Short, Long, ArgSpec, Help}], Args :: string() | [string()]) ->
4542 {ok, {Options, NonOptionArgs}} | {error, {Reason, Data}}
4643
5552 CmdLineTail :: string(), OptionsTail :: [{string(), string}]) -> ok
5653 ```
5754
58 The ``parse/2`` function receives a list of tuples with the command line option
55 The `parse/2` function receives a list of tuples with the command line option
5956 specifications. The type specification for the tuple is:
6057
61 ``` erlang
58 ```erlang
6259 -type arg_type() :: 'atom' | 'binary' | 'boolean' | 'float' | 'integer' | 'string'.
6360
6461 -type arg_value() :: atom() | binary() | boolean() | float() | integer() | string().
7673
7774 The elements of the tuple are:
7875
79 - ``Name``: name of the option.
80 - ``Short``: character for the short option (e.g. $i for -i).
81 - ``Long``: string for the long option (e.g. "info" for --info).
82 - ``ArgSpec``: data type and optional default value the argument will be converted to.
83 - ``Help``: help message that is shown for the option when ``usage/2`` is called.
76 - `Name`: name of the option.
77 - `Short`: character for the short option (e.g. $i for -i).
78 - `Long`: string for the long option (e.g. "info" for --info).
79 - `ArgSpec`: data type and optional default value the argument will be converted to.
80 - `Help`: help message that is shown for the option when `usage/2` is called.
8481
8582 e.g.
8683
87 ``` erlang
84 ```erlang
8885 {port, $p, "port", {integer, 5432}, "Database server port"}
8986 ```
9087
91 The second parameter receives the list of arguments as passed to the ``main/1``
88 The second parameter receives the list of arguments as passed to the `main/1`
9289 function in escripts or the unparsed command line as a string.
9390
9491 If the function is successful parsing the command line arguments it will return
9592 a tuple containing the parsed options and the non-option arguments. The options
96 will be represented by a list of key-value pairs with the ``Name`` of the
93 will be represented by a list of key-value pairs with the `Name` of the
9794 option as *key* and the argument from the command line as *value*. If the option
98 doesn't have an argument, only the atom corresponding to its ``Name`` will be
95 doesn't have an argument, only the atom corresponding to its `Name` will be
9996 added to the list of options. For the example given above we could get something
100 like ``{port, 5432}``. The non-option arguments are just a list of strings with
97 like `{port, 5432}`. The non-option arguments are just a list of strings with
10198 all the arguments that did not have corresponding options.
10299
103100 e.g. Given the following option specifications:
104101
105 ``` erlang
102 ```erlang
106103 OptSpecList =
107104 [
108105 {host, $h, "host", {string, "localhost"}, "Database server host"},
116113
117114 And this command line:
118115
119 ``` erlang
116 ```erlang
120117 Args = "-h myhost --port=1000 -x myfile.txt -vvv dummy1 dummy2"
121118 ```
122119
123 Which could also be passed in the format the ``main/1`` function receives the arguments in escripts:
124
125 ``` erlang
120 Which could also be passed in the format the `main/1` function receives the arguments in escripts:
121
122 ```erlang
126123 Args = ["-h", "myhost", "--port=1000", "-x", "file.txt", "-vvv", "dummy1", "dummy2"].
127124 ```
128125
129 The call to ``getopt:parse/2``:
130
131 ``` erlang
126 The call to `getopt:parse/2`:
127
128 ```erlang
132129 getopt:parse(OptSpecList, Args).
133130 ```
134131
135132 Will return:
136133
137 ``` erlang
134 ```erlang
138135 {ok,{[{host,"myhost"},
139136 {port,1000},
140137 xml,
144141 ["dummy1","dummy2"]}}
145142 ```
146143
147 The ``tokenize/1`` function will separate a command line string into
144 The `tokenize/1` function will separate a command line string into
148145 tokens, taking into account whether an argument is single or double
149146 quoted, a character is escaped or if there are environment variables to
150147 be expanded. e.g.:
151148
152 ``` erlang
149 ```erlang
153150 getopt:tokenize(" --name John\\ Smith --path \"John's Files\" -u ${USER}").
154151 ```
155152
156153 Will return something like:
157154
158 ``` erlang
155 ```erlang
159156 ["--name","John Smith","--path","John's Files","-u","jsmith"]
160157 ```
161158
162 The other functions exported by the ``getopt`` module (``usage/2``, ``usage/3``
163 and ``usage/4``) are used to show the command line syntax for the program.
159 The other functions exported by the `getopt` module (`usage/2`, `usage/3`
160 and `usage/4`) are used to show the command line syntax for the program.
164161 For example, given the above-mentioned option specifications, the call to
165 ``getopt:usage/2``:
166
167 ``` erlang
162 `getopt:usage/2`:
163
164 ```erlang
168165 getopt:usage(OptSpecList, "ex1").
169166 ```
170167
179176 -v Verbosity level
180177 <file> Output file
181178
182 This call to ``getopt:usage/3`` will add a string after the usage command line:
183
184 ``` erlang
185 getopt:usage(OptSpecList, "ex1", "[var=value ...] [command ...]").
179 This call to `getopt:usage/3` will add a string after the usage command line:
180
181 ```erlang
182 getopt:usage(OptSpecList, "ex1", "[var=value ...] [command ...]").
186183 ```
187184
188185 Will show (on *standard_error*):
196193 -v, --verbose Verbosity level
197194 <file> Output file
198195
199 Whereas this call to ``getopt:usage/3`` will also add some lines to the options
196 Whereas this call to `getopt:usage/3` will also add some lines to the options
200197 help text:
201198
202 ``` erlang
199 ```erlang
203200 getopt:usage(OptSpecList, "ex1", "[var=value ...] [command ...]",
204201 [{"var=value", "Variables that will affect the execution (e.g. debug=1)"},
205202 {"command", "Commands that will be executed (e.g. count)"}]).
222219 Command-line Syntax
223220 -------------------
224221
225 The syntax supported by the ``getopt`` module is very similar to that followed
222 The syntax supported by the `getopt` module is very similar to that followed
226223 by GNU programs, which is described [here](http://www.gnu.org/s/libc/manual/html_node/Argument-Syntax.html).
227224
228225 Options can have both short (single character) and long (string) option names.
247244 --------------
248245
249246 The arguments allowed for options are: *atom*; *binary*; *boolean*; *float*; *integer*; *string*.
250 The ``getopt`` module checks every argument to see if it can be converted to its
247 The `getopt` module checks every argument to see if it can be converted to its
251248 correct type.
252249
253250 In the case of boolean arguments, the following values (in lower or
254 upper case) are considered ``true``: *true*; *t*; *yes*; *y*; *on*; *enabled*; *1*.
255 These ones are considered ``false``: *false*; *f*; *no*; *n*; *off*; *disabled*; *0*.
251 upper case) are considered `true`: *true*; *t*; *yes*; *y*; *on*; *enabled*; *1*.
252 These ones are considered `false`: *false*; *f*; *no*; *n*; *off*; *disabled*; *0*.
256253
257254 Numeric arguments can only be negative when passed as part of an assignment expression.
258255
259 e.g. ``--increment=-100`` is a valid expression; whereas ``--increment -100`` is invalid
256 e.g. `--increment=-100` is a valid expression; whereas `--increment -100` is invalid
260257
261258
262259 Implicit Arguments
278275
279276 e.g. Given an option specification list with the following format:
280277
281 ``` erlang
278 ```erlang
282279 OptSpecList =
283280 [
284281 {define, $D, "define", string, "Define a variable"},
288285
289286 The following invocation:
290287
291 ``` erlang
288 ```erlang
292289 getopt:parse(OptSpecList, "-DFOO -DVAR1=VAL1 -DBAR --verbose --verbose=3 -v -vvvv dummy").
293290 ```
294291
295292 would return:
296293
297 ``` erlang
294 ```erlang
298295 {ok,{[{define,"FOO"}, {define,"VAR1=VAL1"}, {define,"BAR"},
299296 {verbose,1}, {verbose,3}, {verbose,1}, {verbose,4}],
300297 ["dummy"]}}
306303
307304 We can also have options with neither short nor long option names. In this case,
308305 the options will be taken according to their position in the option specification
309 list passed to ``getopt:/parse2``.
306 list passed to `getopt:/parse2`.
310307
311308 For example, with the following option specifications:
312309
313 ``` erlang
310 ```erlang
314311 OptSpecList =
315312 [
316313 {xml, $x, "xml", undefined, "Output data as XML"},
319316 ].
320317 ```
321318
322 This call to ``getopt:parse/2``:
323
324 ``` erlang
319 This call to `getopt:parse/2`:
320
321 ```erlang
325322 getopt:parse(OptSpecList, "-x mydb file.out dummy dummy").
326323 ```
327324
328325 Will return:
329326
330 ``` erlang
327 ```erlang
331328 {ok,{[xml,{dbname,"mydb"},{output_file,"file.out"}],
332329 ["dummy","dummy"]}}
333330 ```
336333 Option Terminators
337334 ------------------
338335
339 The string ``--`` is considered an option terminator. This means that all the
336 The string `--` is considered an option terminator. This means that all the
340337 command-line arguments after it are considered non-option arguments and will be
341338 returned without being evaluated even if they follow the *getopt* syntax.
342339
343340 e.g. This invocation using the first option specification list in the document:
344341
345 ``` erlang
342 ```erlang
346343 getopt:parse(OptSpecList, "-h myhost -p 1000 -- --dbname mydb dummy").
347344 ```
348345
349346 will return:
350347
351 ``` erlang
348 ```erlang
352349 {ok,{[{host,"myhost"}, {port,1000},{dbname,"users"}],
353350 ["--dbname","mydb","dummy"]}}
354351 ```
355352
356 Notice that the *dbname* option was assigned the value ``users`` instead of ``mydb``.
353 Notice that the *dbname* option was assigned the value `users` instead of `mydb`.
357354 This happens because the option terminator prevented *getopt* from evaluating it
358355 and the default value was assigned to it.
359356
361358 Non-option Arguments
362359 --------------------
363360
364 The single ``-`` character is always considered as a non-option argument.
361 The single `-` character is always considered as a non-option argument.
365362
366363 e.g. This invocation using the specification list from the previous example:
367364
368 ``` erlang
365 ```erlang
369366 getopt:parse(OptSpecList, "-h myhost -p 1000 - --dbname mydb dummy").
370367 ```
371368
372369 will return:
373370
374 ``` erlang
371 ```erlang
375372 {ok,{[{host,"myhost"}, {port,1000}, {dbname,"mydb"}],
376373 ["-","dummy"]}}
377374 ```
387384
388385 e.g. Given an option specification list with the following format:
389386
390 ``` erlang
387 ```erlang
391388 OptSpecList =
392389 [
393390 {define, $D, "define", string, "Define a variable"},
397394
398395 The following invocation:
399396
400 ``` erlang
397 ```erlang
401398 getopt:parse(OptSpecList,
402399 "-D'FOO=VAR 123' --define \"VAR WITH SPACES\" -u\"my user name\"").
403400 ```
404401
405402 would return:
406403
407 ``` erlang
404 ```erlang
408405 {ok,{[{define,"FOO=VAR 123"},
409406 {define,"VAR WITH SPACES"},
410407 {user,"my user name"}],
417414
418415 e.g. The following invocation:
419416
420 ``` erlang
417 ```erlang
421418 getopt:parse(OptSpecList, "--user ' my user ' \"argument with unclosed quotes").
422419 ```
423420
424421 would return:
425422
426 ``` erlang
423 ```erlang
427424 {ok,{[{user," my user "}],
428425 ["argument with unclosed quotes"]}}
429426 ```
447444
448445 e.g. Given the following option specification list:
449446
450 ``` erlang
447 ```erlang
451448 OptSpecList =
452449 [
453450 {path, $p, "path", string, "File path"}
456453
457454 The following invocation:
458455
459 ``` erlang
456 ```erlang
460457 getopt:parse(OptSpecList, "--path ${PATH} $NONEXISTENT_DUMMY_VAR").
461458 ```
462459
463460 would return (depending on the value of your PATH variable) something like:
464461
465 ``` erlang
462 ```erlang
466463 {ok,{[{path, "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}],
467464 ["$NONEXISTENT_DUMMY_VAR"]}}
468465 ```
478475
479476 e.g.
480477
481 ``` erlang
478 ```erlang
482479 getopt:parse(OptSpecList, "--path /john\\'s\\ files dummy").
483480 ```
484481
485482 Will return:
486483
487 ``` erlang
484 ```erlang
488485 {ok,{[{path,"/john's files"}],["dummy"]}}
489486 ```
1010 warn_export_vars,
1111 warn_exported_vars,
1212 warn_missing_spec,
13 warn_untyped_record, debug_info]}.
13 warn_untyped_record, debug_info,
14 {platform_define, "^2", unicode_str}
15 ]}.
16
17 {dialyzer,
18 [
19 {warnings, [no_return, no_undefined_callbacks, no_unused]},
20 {get_warnings, true},
21 {plt_apps, top_level_deps},
22 {plt_location, local},
23 {base_plt_apps, [kernel, stdlib, sasl, inets, crypto, public_key, ssl,
24 runtime_tools, erts, compiler, tools, syntax_tools, hipe,
25 mnesia]},
26 {base_plt_location, global}
27 ]}.
28
1429 {xref_checks, [undefined_function_calls]}.
00 %% -*- mode: Erlang; fill-column: 75; comment-column: 50; -*-
11 {application, getopt,
22 [{description, "Command-line options parser for Erlang"},
3 {vsn, "0.8.2"},
3 {vsn, "1.0.1"},
44 {modules, []},
55 {registered, []},
6 {maintainers, ["Juan Jose Comellas"]},
7 {licenses, ["BSD"]},
8 {links, [{"GitHub", "https://github.com/jcomellas/getopt"}]},
69 {applications, [kernel, stdlib]}]}.
00 %%%-------------------------------------------------------------------
11 %%% @author Juan Jose Comellas <juanjo@comellas.org>
2 %%% @copyright (C) 2009 Juan Jose Comellas
2 %%% @copyright (C) 2009-2017 Juan Jose Comellas
33 %%% @doc Parses command line options with a format similar to that of GNU getopt.
44 %%% @end
55 %%%
1111 -author('juanjo@comellas.org').
1212
1313 -export([parse/2, check/2, parse_and_check/2, format_error/2,
14 usage/2, usage/3, usage/4, tokenize/1]).
14 usage/2, usage/3, usage/4, usage/6, tokenize/1]).
1515 -export([usage_cmd_line/2]).
1616
1717 -define(LINE_LENGTH, 75).
148148 format_error(OptSpecList, {error, Reason}) ->
149149 format_error(OptSpecList, Reason);
150150 format_error(OptSpecList, {missing_required_option, Name}) ->
151 {_Name, Short, Long, _Type, _Help} = lists:keyfind(Name, 1, OptSpecList),
152 lists:flatten(["missing required option: -", [Short], " (", to_string(Long), ")"]);
151 OptStr = case lists:keyfind(Name, 1, OptSpecList) of
152 {Name, undefined, undefined, _Type, _Help} -> ["<", to_string(Name), ">"];
153 {_Name, undefined, Long, _Type, _Help} -> ["--", Long];
154 {_Name, Short, undefined, _Type, _Help} -> ["-", Short];
155 {_Name, Short, Long, _Type, _Help} -> ["-", Short, " (", Long, ")"]
156 end,
157 lists:flatten(["missing required option: ", OptStr]);
153158 format_error(_OptSpecList, {invalid_option, OptStr}) ->
154159 lists:flatten(["invalid option: ", to_string(OptStr)]);
155160 format_error(_OptSpecList, {invalid_option_arg, {Name, Arg}}) ->
436441 to_type(float, Arg) ->
437442 list_to_float(Arg);
438443 to_type(boolean, Arg) ->
439 LowerArg = string:to_lower(Arg),
444 LowerArg = lowercase(Arg),
440445 case is_arg_true(LowerArg) of
441446 true ->
442447 true;
494499
495500 -spec is_boolean_arg(string()) -> boolean().
496501 is_boolean_arg(Arg) ->
497 LowerArg = string:to_lower(Arg),
502 LowerArg = lowercase(Arg),
498503 is_arg_true(LowerArg) orelse is_arg_false(LowerArg).
499504
500505
534539 %% arguments that are supported by the program.
535540 -spec usage([option_spec()], string(), output_stream() | string()) -> ok.
536541 usage(OptSpecList, ProgramName, OutputStream) when is_atom(OutputStream) ->
537 io:format(OutputStream, "~s~n~n~s~n",
538 [usage_cmd_line(ProgramName, OptSpecList), usage_options(OptSpecList)]);
542 io:format(OutputStream, "~ts~n~n~ts~n",
543 [unicode:characters_to_list(usage_cmd_line(ProgramName, OptSpecList)), unicode:characters_to_list(usage_options(OptSpecList))]);
539544 %% @doc Show a message on standard_error indicating the command line options and
540545 %% arguments that are supported by the program. The CmdLineTail argument
541546 %% is a string that is added to the end of the usage command line.
548553 %% is a string that is added to the end of the usage command line.
549554 -spec usage([option_spec()], ProgramName :: string(), CmdLineTail :: string(), output_stream() | [{string(), string()}]) -> ok.
550555 usage(OptSpecList, ProgramName, CmdLineTail, OutputStream) when is_atom(OutputStream) ->
551 io:format(OutputStream, "~s~n~n~s~n",
552 [usage_cmd_line(ProgramName, OptSpecList, CmdLineTail), usage_options(OptSpecList)]);
556 io:format(OutputStream, "~ts~n~n~ts~n",
557 [unicode:characters_to_list(usage_cmd_line(ProgramName, OptSpecList, CmdLineTail)), unicode:characters_to_list(usage_options(OptSpecList))]);
553558 %% @doc Show a message on standard_error indicating the command line options and
554559 %% arguments that are supported by the program. The CmdLineTail and OptionsTail
555560 %% arguments are a string that is added to the end of the usage command line
565570 -spec usage([option_spec()], ProgramName :: string(), CmdLineTail :: string(),
566571 [{OptionName :: string(), Help :: string()}], output_stream()) -> ok.
567572 usage(OptSpecList, ProgramName, CmdLineTail, OptionsTail, OutputStream) ->
568 io:format(OutputStream, "~s~n~n~s~n",
569 [usage_cmd_line(ProgramName, OptSpecList, CmdLineTail), usage_options(OptSpecList, OptionsTail)]).
573 io:format(OutputStream, "~ts~n~n~ts~n",
574 [unicode:characters_to_list(usage_cmd_line(ProgramName, OptSpecList, CmdLineTail)), unicode:characters_to_list(usage_options(OptSpecList, OptionsTail))]).
575
576 %% @doc Show a message on standard_error or standard_io indicating the
577 %% command line options and arguments that are supported by the
578 %% program. The Description allows for structured command line usage
579 %% that works in addition to the standard options, and appears between
580 %% the usage_cmd_line and usage_options sections. The CmdLineTail and
581 %% OptionsTail arguments are a string that is added to the end of the
582 %% usage command line and a list of tuples that are added to the end of
583 %% the options' help lines.
584 -spec usage([option_spec()], ProgramName :: string(), CmdLineTail :: string(),
585 Description :: string(),
586 [{OptionName :: string(), Help :: string()}],
587 output_stream()) -> ok.
588 usage(OptSpecList, ProgramName, CmdLineTail, Description, OptionsTail, OutputStream) ->
589 io:format(OutputStream, "~ts~n~n~ts~n~n~ts~n",
590 [unicode:characters_to_list(usage_cmd_line(ProgramName, OptSpecList, CmdLineTail)), Description, unicode:characters_to_list(usage_options(OptSpecList, OptionsTail))]).
570591
571592
572593 -spec usage_cmd_line(ProgramName :: string(), [option_spec()]) -> iolist().
597618 %% already wrapped according to the maximum MaxLineLength.
598619 -spec usage_cmd_line_options(MaxLineLength :: non_neg_integer(), [option_spec()], CmdLineTail :: string()) -> iolist().
599620 usage_cmd_line_options(MaxLineLength, OptSpecList, CmdLineTail) ->
600 usage_cmd_line_options(MaxLineLength, OptSpecList ++ string:tokens(CmdLineTail, " "), [], 0, []).
621 usage_cmd_line_options(MaxLineLength, OptSpecList ++ lexemes(CmdLineTail, " "), [], 0, []).
601622
602623 usage_cmd_line_options(MaxLineLength, [OptSpec | Tail], LineAcc, LineAccLength, Acc) ->
603624 Option = [$\s | lists:flatten(usage_cmd_line_option(OptSpec))],
768789 %% Look for the first whitespace character in the current (reversed) line
769790 %% buffer to get a wrapped line. If there is no whitespace just cut the
770791 %% line at the position corresponding to the maximum length.
771 {NextLineAcc, WrappedLine} = case string:cspan(CurrentLineAcc, " \t") of
792 {NextLineAcc, WrappedLine} = case cspan(CurrentLineAcc, " \t") of
772793 WhitespacePos when WhitespacePos < Count ->
773794 lists:split(WhitespacePos, CurrentLineAcc);
774795 _ ->
911932 atom_to_list(Atom);
912933 to_string(Value) ->
913934 io_lib:format("~p", [Value]).
935
936 %% OTP-20/21 conversion to unicode string module
937 -ifdef(unicode_str).
938 lowercase(Str) -> string:lowercase(Str).
939 lexemes(Str, Separators) -> string:lexemes(Str, Separators).
940 cspan(Str, Chars) -> length(element(1,string:take(Str, Chars, true))).
941 -else.
942 lowercase(Str) -> string:to_lower(Str).
943 lexemes(Str, Separators) -> string:tokens(Str, Separators).
944 cspan(Str, Chars) -> string:cspan(Str, Chars).
945 -endif.
946
286286 check_test_() ->
287287 OptSpecList =
288288 [
289 {arg, $a, "arg", string, "Required arg"}
289 { arg, $a, "arg", string, "Required arg"},
290 {short, $s, undefined, string, "short option"},
291 { long, undefined, "long", string, "long option"},
292 {other, undefined, undefined, string, "task"}
290293 ],
291294 {ok, {Opts, _}} = parse(OptSpecList, ""),
292295 [
300303 {"Format missing option error test 2",
301304 ?_assertEqual("missing required option: -a (arg)",
302305 format_error(OptSpecList, {missing_required_option, arg}))},
306 {"Format missing option error test 3",
307 ?_assertEqual("missing required option: -s",
308 format_error(OptSpecList, {missing_required_option, short}))},
309 {"Format missing option error test 4",
310 ?_assertEqual("missing required option: --long",
311 format_error(OptSpecList, {missing_required_option, long}))},
312 {"Format missing option error test 5",
313 ?_assertEqual("missing required option: <other>",
314 format_error(OptSpecList, {missing_required_option, other}))},
303315 {"Format invalid option error test 1",
304316 ?_assertEqual("invalid option: --verbose",
305317 format_error(OptSpecList, {error, {invalid_option, "--verbose"}}))},