7 | 7 |
------------
|
8 | 8 |
|
9 | 9 |
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.
|
19 | 14 |
|
20 | 15 |
Installation
|
21 | 16 |
------------
|
22 | 17 |
|
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:
|
33 | 26 |
```sh
|
34 | |
ln -s . /usr/local/lib/erlang/lib/getopt-0.8.2
|
|
27 |
{deps,
|
|
28 |
[
|
|
29 |
{getopt, "1.0.1"}
|
|
30 |
]
|
|
31 |
}
|
35 | 32 |
```
|
36 | 33 |
|
37 | 34 |
|
38 | 35 |
Usage
|
39 | 36 |
-----
|
40 | 37 |
|
41 | |
The *getopt* module provides four functions:
|
42 | |
|
43 | |
``` erlang
|
|
38 |
The `getopt` module provides four functions:
|
|
39 |
|
|
40 |
```erlang
|
44 | 41 |
parse([{Name, Short, Long, ArgSpec, Help}], Args :: string() | [string()]) ->
|
45 | 42 |
{ok, {Options, NonOptionArgs}} | {error, {Reason, Data}}
|
46 | 43 |
|
|
55 | 52 |
CmdLineTail :: string(), OptionsTail :: [{string(), string}]) -> ok
|
56 | 53 |
```
|
57 | 54 |
|
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
|
59 | 56 |
specifications. The type specification for the tuple is:
|
60 | 57 |
|
61 | |
``` erlang
|
|
58 |
```erlang
|
62 | 59 |
-type arg_type() :: 'atom' | 'binary' | 'boolean' | 'float' | 'integer' | 'string'.
|
63 | 60 |
|
64 | 61 |
-type arg_value() :: atom() | binary() | boolean() | float() | integer() | string().
|
|
76 | 73 |
|
77 | 74 |
The elements of the tuple are:
|
78 | 75 |
|
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.
|
84 | 81 |
|
85 | 82 |
e.g.
|
86 | 83 |
|
87 | |
``` erlang
|
|
84 |
```erlang
|
88 | 85 |
{port, $p, "port", {integer, 5432}, "Database server port"}
|
89 | 86 |
```
|
90 | 87 |
|
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`
|
92 | 89 |
function in escripts or the unparsed command line as a string.
|
93 | 90 |
|
94 | 91 |
If the function is successful parsing the command line arguments it will return
|
95 | 92 |
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
|
97 | 94 |
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
|
99 | 96 |
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
|
101 | 98 |
all the arguments that did not have corresponding options.
|
102 | 99 |
|
103 | 100 |
e.g. Given the following option specifications:
|
104 | 101 |
|
105 | |
``` erlang
|
|
102 |
```erlang
|
106 | 103 |
OptSpecList =
|
107 | 104 |
[
|
108 | 105 |
{host, $h, "host", {string, "localhost"}, "Database server host"},
|
|
116 | 113 |
|
117 | 114 |
And this command line:
|
118 | 115 |
|
119 | |
``` erlang
|
|
116 |
```erlang
|
120 | 117 |
Args = "-h myhost --port=1000 -x myfile.txt -vvv dummy1 dummy2"
|
121 | 118 |
```
|
122 | 119 |
|
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
|
126 | 123 |
Args = ["-h", "myhost", "--port=1000", "-x", "file.txt", "-vvv", "dummy1", "dummy2"].
|
127 | 124 |
```
|
128 | 125 |
|
129 | |
The call to ``getopt:parse/2``:
|
130 | |
|
131 | |
``` erlang
|
|
126 |
The call to `getopt:parse/2`:
|
|
127 |
|
|
128 |
```erlang
|
132 | 129 |
getopt:parse(OptSpecList, Args).
|
133 | 130 |
```
|
134 | 131 |
|
135 | 132 |
Will return:
|
136 | 133 |
|
137 | |
``` erlang
|
|
134 |
```erlang
|
138 | 135 |
{ok,{[{host,"myhost"},
|
139 | 136 |
{port,1000},
|
140 | 137 |
xml,
|
|
144 | 141 |
["dummy1","dummy2"]}}
|
145 | 142 |
```
|
146 | 143 |
|
147 | |
The ``tokenize/1`` function will separate a command line string into
|
|
144 |
The `tokenize/1` function will separate a command line string into
|
148 | 145 |
tokens, taking into account whether an argument is single or double
|
149 | 146 |
quoted, a character is escaped or if there are environment variables to
|
150 | 147 |
be expanded. e.g.:
|
151 | 148 |
|
152 | |
``` erlang
|
|
149 |
```erlang
|
153 | 150 |
getopt:tokenize(" --name John\\ Smith --path \"John's Files\" -u ${USER}").
|
154 | 151 |
```
|
155 | 152 |
|
156 | 153 |
Will return something like:
|
157 | 154 |
|
158 | |
``` erlang
|
|
155 |
```erlang
|
159 | 156 |
["--name","John Smith","--path","John's Files","-u","jsmith"]
|
160 | 157 |
```
|
161 | 158 |
|
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.
|
164 | 161 |
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
|
168 | 165 |
getopt:usage(OptSpecList, "ex1").
|
169 | 166 |
```
|
170 | 167 |
|
|
179 | 176 |
-v Verbosity level
|
180 | 177 |
<file> Output file
|
181 | 178 |
|
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 ...]").
|
186 | 183 |
```
|
187 | 184 |
|
188 | 185 |
Will show (on *standard_error*):
|
|
196 | 193 |
-v, --verbose Verbosity level
|
197 | 194 |
<file> Output file
|
198 | 195 |
|
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
|
200 | 197 |
help text:
|
201 | 198 |
|
202 | |
``` erlang
|
|
199 |
```erlang
|
203 | 200 |
getopt:usage(OptSpecList, "ex1", "[var=value ...] [command ...]",
|
204 | 201 |
[{"var=value", "Variables that will affect the execution (e.g. debug=1)"},
|
205 | 202 |
{"command", "Commands that will be executed (e.g. count)"}]).
|
|
222 | 219 |
Command-line Syntax
|
223 | 220 |
-------------------
|
224 | 221 |
|
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
|
226 | 223 |
by GNU programs, which is described [here](http://www.gnu.org/s/libc/manual/html_node/Argument-Syntax.html).
|
227 | 224 |
|
228 | 225 |
Options can have both short (single character) and long (string) option names.
|
|
247 | 244 |
--------------
|
248 | 245 |
|
249 | 246 |
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
|
251 | 248 |
correct type.
|
252 | 249 |
|
253 | 250 |
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*.
|
256 | 253 |
|
257 | 254 |
Numeric arguments can only be negative when passed as part of an assignment expression.
|
258 | 255 |
|
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
|
260 | 257 |
|
261 | 258 |
|
262 | 259 |
Implicit Arguments
|
|
278 | 275 |
|
279 | 276 |
e.g. Given an option specification list with the following format:
|
280 | 277 |
|
281 | |
``` erlang
|
|
278 |
```erlang
|
282 | 279 |
OptSpecList =
|
283 | 280 |
[
|
284 | 281 |
{define, $D, "define", string, "Define a variable"},
|
|
288 | 285 |
|
289 | 286 |
The following invocation:
|
290 | 287 |
|
291 | |
``` erlang
|
|
288 |
```erlang
|
292 | 289 |
getopt:parse(OptSpecList, "-DFOO -DVAR1=VAL1 -DBAR --verbose --verbose=3 -v -vvvv dummy").
|
293 | 290 |
```
|
294 | 291 |
|
295 | 292 |
would return:
|
296 | 293 |
|
297 | |
``` erlang
|
|
294 |
```erlang
|
298 | 295 |
{ok,{[{define,"FOO"}, {define,"VAR1=VAL1"}, {define,"BAR"},
|
299 | 296 |
{verbose,1}, {verbose,3}, {verbose,1}, {verbose,4}],
|
300 | 297 |
["dummy"]}}
|
|
306 | 303 |
|
307 | 304 |
We can also have options with neither short nor long option names. In this case,
|
308 | 305 |
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`.
|
310 | 307 |
|
311 | 308 |
For example, with the following option specifications:
|
312 | 309 |
|
313 | |
``` erlang
|
|
310 |
```erlang
|
314 | 311 |
OptSpecList =
|
315 | 312 |
[
|
316 | 313 |
{xml, $x, "xml", undefined, "Output data as XML"},
|
|
319 | 316 |
].
|
320 | 317 |
```
|
321 | 318 |
|
322 | |
This call to ``getopt:parse/2``:
|
323 | |
|
324 | |
``` erlang
|
|
319 |
This call to `getopt:parse/2`:
|
|
320 |
|
|
321 |
```erlang
|
325 | 322 |
getopt:parse(OptSpecList, "-x mydb file.out dummy dummy").
|
326 | 323 |
```
|
327 | 324 |
|
328 | 325 |
Will return:
|
329 | 326 |
|
330 | |
``` erlang
|
|
327 |
```erlang
|
331 | 328 |
{ok,{[xml,{dbname,"mydb"},{output_file,"file.out"}],
|
332 | 329 |
["dummy","dummy"]}}
|
333 | 330 |
```
|
|
336 | 333 |
Option Terminators
|
337 | 334 |
------------------
|
338 | 335 |
|
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
|
340 | 337 |
command-line arguments after it are considered non-option arguments and will be
|
341 | 338 |
returned without being evaluated even if they follow the *getopt* syntax.
|
342 | 339 |
|
343 | 340 |
e.g. This invocation using the first option specification list in the document:
|
344 | 341 |
|
345 | |
``` erlang
|
|
342 |
```erlang
|
346 | 343 |
getopt:parse(OptSpecList, "-h myhost -p 1000 -- --dbname mydb dummy").
|
347 | 344 |
```
|
348 | 345 |
|
349 | 346 |
will return:
|
350 | 347 |
|
351 | |
``` erlang
|
|
348 |
```erlang
|
352 | 349 |
{ok,{[{host,"myhost"}, {port,1000},{dbname,"users"}],
|
353 | 350 |
["--dbname","mydb","dummy"]}}
|
354 | 351 |
```
|
355 | 352 |
|
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`.
|
357 | 354 |
This happens because the option terminator prevented *getopt* from evaluating it
|
358 | 355 |
and the default value was assigned to it.
|
359 | 356 |
|
|
361 | 358 |
Non-option Arguments
|
362 | 359 |
--------------------
|
363 | 360 |
|
364 | |
The single ``-`` character is always considered as a non-option argument.
|
|
361 |
The single `-` character is always considered as a non-option argument.
|
365 | 362 |
|
366 | 363 |
e.g. This invocation using the specification list from the previous example:
|
367 | 364 |
|
368 | |
``` erlang
|
|
365 |
```erlang
|
369 | 366 |
getopt:parse(OptSpecList, "-h myhost -p 1000 - --dbname mydb dummy").
|
370 | 367 |
```
|
371 | 368 |
|
372 | 369 |
will return:
|
373 | 370 |
|
374 | |
``` erlang
|
|
371 |
```erlang
|
375 | 372 |
{ok,{[{host,"myhost"}, {port,1000}, {dbname,"mydb"}],
|
376 | 373 |
["-","dummy"]}}
|
377 | 374 |
```
|
|
387 | 384 |
|
388 | 385 |
e.g. Given an option specification list with the following format:
|
389 | 386 |
|
390 | |
``` erlang
|
|
387 |
```erlang
|
391 | 388 |
OptSpecList =
|
392 | 389 |
[
|
393 | 390 |
{define, $D, "define", string, "Define a variable"},
|
|
397 | 394 |
|
398 | 395 |
The following invocation:
|
399 | 396 |
|
400 | |
``` erlang
|
|
397 |
```erlang
|
401 | 398 |
getopt:parse(OptSpecList,
|
402 | 399 |
"-D'FOO=VAR 123' --define \"VAR WITH SPACES\" -u\"my user name\"").
|
403 | 400 |
```
|
404 | 401 |
|
405 | 402 |
would return:
|
406 | 403 |
|
407 | |
``` erlang
|
|
404 |
```erlang
|
408 | 405 |
{ok,{[{define,"FOO=VAR 123"},
|
409 | 406 |
{define,"VAR WITH SPACES"},
|
410 | 407 |
{user,"my user name"}],
|
|
417 | 414 |
|
418 | 415 |
e.g. The following invocation:
|
419 | 416 |
|
420 | |
``` erlang
|
|
417 |
```erlang
|
421 | 418 |
getopt:parse(OptSpecList, "--user ' my user ' \"argument with unclosed quotes").
|
422 | 419 |
```
|
423 | 420 |
|
424 | 421 |
would return:
|
425 | 422 |
|
426 | |
``` erlang
|
|
423 |
```erlang
|
427 | 424 |
{ok,{[{user," my user "}],
|
428 | 425 |
["argument with unclosed quotes"]}}
|
429 | 426 |
```
|
|
447 | 444 |
|
448 | 445 |
e.g. Given the following option specification list:
|
449 | 446 |
|
450 | |
``` erlang
|
|
447 |
```erlang
|
451 | 448 |
OptSpecList =
|
452 | 449 |
[
|
453 | 450 |
{path, $p, "path", string, "File path"}
|
|
456 | 453 |
|
457 | 454 |
The following invocation:
|
458 | 455 |
|
459 | |
``` erlang
|
|
456 |
```erlang
|
460 | 457 |
getopt:parse(OptSpecList, "--path ${PATH} $NONEXISTENT_DUMMY_VAR").
|
461 | 458 |
```
|
462 | 459 |
|
463 | 460 |
would return (depending on the value of your PATH variable) something like:
|
464 | 461 |
|
465 | |
``` erlang
|
|
462 |
```erlang
|
466 | 463 |
{ok,{[{path, "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}],
|
467 | 464 |
["$NONEXISTENT_DUMMY_VAR"]}}
|
468 | 465 |
```
|
|
478 | 475 |
|
479 | 476 |
e.g.
|
480 | 477 |
|
481 | |
``` erlang
|
|
478 |
```erlang
|
482 | 479 |
getopt:parse(OptSpecList, "--path /john\\'s\\ files dummy").
|
483 | 480 |
```
|
484 | 481 |
|
485 | 482 |
Will return:
|
486 | 483 |
|
487 | |
``` erlang
|
|
484 |
```erlang
|
488 | 485 |
{ok,{[{path,"/john's files"}],["dummy"]}}
|
489 | 486 |
```
|