Skip to content

Commit

Permalink
Dropped record syntax for the option specifications to simplify use f…
Browse files Browse the repository at this point in the history
…rom escripts.
  • Loading branch information
Juan Jose Comellas committed Nov 16, 2009
1 parent 109d9f5 commit 4b03285
Show file tree
Hide file tree
Showing 8 changed files with 270 additions and 329 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
@@ -0,0 +1,9 @@
2009-11-16 Juan Jose Comellas <juanjo@comellas.org>

* *: Released v0.1

* src/getopt.erl:
* src/test/getopt_test.erl:
* src/examples/ex1.erl:

Dropped record syntax for the option specifications to simplify use from escripts.
6 changes: 3 additions & 3 deletions LICENSE.txt
@@ -1,4 +1,4 @@
Copyright (c) 2009, Novamens SA Copyright (c) 2009 Juan Jose Comellas
All rights reserved. All rights reserved.


Redistribution and use in source and binary forms, with or without modification, Redistribution and use in source and binary forms, with or without modification,
Expand All @@ -11,8 +11,8 @@ are permitted provided that the following conditions are met:
this list of conditions and the following disclaimer in the documentation this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution. and/or other materials provided with the distribution.


- Neither the name of Novamens SA nor the names of its contributors may be - Neither the name of Juan Jose Comellas nor the names of its contributors may
used to endorse or promote products derived from this software without be used to endorse or promote products derived from this software without
specific prior written permission. specific prior written permission.


THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
Expand Down
98 changes: 33 additions & 65 deletions README.markdown
Expand Up @@ -28,81 +28,59 @@ Usage


The *getopt* module provides two functions: The *getopt* module provides two functions:


parse([#option{}], Args :: string() | [string()]) -> parse([{Name, Short, Long, ArgSpec, Help}], Args :: string() | [string()]) ->
{ok, {Options, NonOptionArgs}} | {error, {Reason, Data}} {ok, {Options, NonOptionArgs}} | {error, {Reason, Data}}


usage([#option{}], ProgramName :: string()) -> ok usage([{Name, Short, Long, ArgSpec, Help}], ProgramName :: string()) -> ok


The ``parse/2`` function receives a list of ``#option{}`` records (defined in The ``parse/2`` function receives a list of tuples with the command line option
``getopt.hrl``) with the command line option specifications. The ``#option{}`` specifications. The type specification for the tuple is:
record has the following elements:


-record(option, { -type arg_type() :: 'atom' | 'binary' | 'boolean' | 'float' | 'integer' | 'string'.
name :: atom(),
short :: char() | undefined, -type arg_value() :: atom() | binary() | boolean() | float() | integer() | string().
long :: string() | undefined,
arg :: getopt_arg_type() | {getopt_arg_type(), getopt_arg()} | undefined. -type arg_spec() :: arg_type() | {arg_type(), arg_value()} | undefined.
help :: string() | undefined
}). -type option_spec() :: {
Name :: atom(),
Short :: char() | undefined,
Long :: string() | undefined,
ArgSpec :: arg_spec(),
Help :: string() | undefined
}.


The fields of the record are: The fields of the record are:


- ``name``: name of the option. - ``Name``: name of the option.
- ``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).
- ``arg``: data type the argument will be converted to with an optional default value. It can either be an atom() (one of: 'atom', 'binary', 'boolean', 'float', 'integer', 'string') or a tuple with an atom() and the default value for that argument. - ``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. function in escripts. e.g.

e.g.


#option{name = port, {port, $p, "port", {integer, 5432}, "Database server port"}
short = $p,
long = "port",
arg = {integer, 5432},
help = "Database server port"
}


If the function is successful parsing the command line arguments it will return If the function is successful parsing the command line arguments it will return
a tuple containing the parsed options and the non-option arguments. The options a tuple containing the parsed options and the non-option arguments. The options
will be represented by a list of key-value pairs with the ``name`` of the will be represented by a list of key-value pairs with the ``Name`` of the
option as *key* and the argument from the command line as *value*. If the option option as *key* and the argument from the command line as *value*. If the option
doesn't have an argument, only the atom corresponding to its ``name`` will be doesn't have an argument, only the atom corresponding to its ``Name`` will be
added to the list of options. For the example given above we could get something added to the list of options. For the example given above we could get something
like ``{port, 5432}``. The non-option arguments are just a list of strings with like ``{port, 5432}``. The non-option arguments are just a list of strings with
all the arguments that did not have corresponding options. all the arguments that did not have corresponding options.


e.g. For a program named ``ex1.escript`` with the following option specifications: e.g. For a program named ``ex.escript`` with the following option specifications:


OptSpec = OptSpec =
[ [
#option{name = host, {host, $h, "host", {string, "localhost"}, "Database server host"},
short = $h, {port, $p, "port", integer, "Database server port"},
long = "host", {dbname, undefined, "dbname", {string, "users"}, "Database name"},
arg = {string, "localhost"}, {xml, $x, undefined, undefined, "Output data in XML"},
help = "Database server host" {file, undefined, undefined, string, "Output file"}
},
#option{name = port,
short = $p,
long = "port",
arg = integer,
help = "Database server port"
},
#option{name = dbname,
long = "dbname",
arg = {string, "users"},
help = "Database name"
},
#option{name = xml,
short = $x,
help = "Output data in XML"
},
#option{name = file,
arg = string,
help = "Output file"
}
]. ].


And this command line: And this command line:
Expand Down Expand Up @@ -132,7 +110,7 @@ Also, the call to ``getopt:usage/2``:


Will show (on *stdout*): Will show (on *stdout*):


Usage: ex1 [-h <host>] [-p <port>] [--dbname <dbname>] [-x] <file> Usage: ex.escript [-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
Expand All @@ -146,13 +124,3 @@ Known limitations


- The syntax for non-option arguments that start with '-' (e.g. -a -- -b) - The syntax for non-option arguments that start with '-' (e.g. -a -- -b)
is not supported yet. is not supported yet.


Known problems
--------------

Currently, with Erlang R13B (and older versions), escripts cannot use the
``-include()`` preprocessor directive so you're forced to install the *getopt*
package in Erlang's library path for your escripts to be able to include the
``getopt.hrl`` header file that defines the ``#option{}`` record used by the
functions in the *getopt* module.
51 changes: 51 additions & 0 deletions examples/ex1.escript
@@ -0,0 +1,51 @@
#!/usr/bin/env escript
%% -*- erlang -*-
%%! -sname ex1 -pz ebin

%%%-------------------------------------------------------------------
%%% @author Juan Jose Comellas <juanjo@comellas.org>
%%% @copyright (C) 2009 Juan Jose Comellas
%%% @doc Example file for the getopt module.
%%% @end
%%%
%%% This source file is subject to the New BSD License. You should have received
%%% a copy of the New BSD license with this software. If not, it can be
%%% retrieved from: http://www.opensource.org/licenses/bsd-license.php
%%%-------------------------------------------------------------------
-module(ex1).
-author('juanjo@comellas.org').

main([]) ->
getopt:usage(option_spec_list(), "ex1.escript");
main(Args) ->
OptSpecList = option_spec_list(),

io:format("For command line: ~p~n"
"getopt:parse/2 returns:~n~n", [Args]),
case getopt:parse(OptSpecList, Args) of
{ok, {Options, NonOptArgs}} ->
io:format("Options:~n ~p~n~nNon-option arguments:~n ~p~n", [Options, NonOptArgs]);
{error, {Reason, Data}} ->
io:format("Error: ~s ~p~n~n", [Reason, Data]),
getopt:usage(OptSpecList, "ex1.escript")
end.


option_spec_list() ->
CurrentUser = case os:getenv("USER") of
false ->
"user";
User ->
User
end,
[
%% {Name, ShortOpt, LongOpt, ArgSpec, HelpMsg}
{help, $?, "help", undefined, "Show the program options"},
{username, $U, "username", string, "Username to connect to the database"},
{password, $P, "password", {string, CurrentUser}, "Password to connect to the database"},
{host, $h, "host", {string, "localhost"}, "Database server host name or IP address"},
{port, $p, "port", {integer, 1000}, "Database server port"},
{output_file, $o, "output-file", string, "File where the data will be saved to"},
{xml, $x, "xml", undefined, "Output data as XML"},
{dbname, undefined, undefined, string, "Database name"}
].
23 changes: 0 additions & 23 deletions include/getopt.hrl

This file was deleted.

63 changes: 13 additions & 50 deletions src/examples/ex1.erl
@@ -1,6 +1,6 @@
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
%%% @author Juan Jose Comellas <jcomellas@novamens.com> %%% @author Juan Jose Comellas <juanjo@comellas.org>
%%% @copyright (C) 2009, Novamens SA (http://www.novamens.com) %%% @copyright (C) 2009 Juan Jose Comellas
%%% @doc Example file for the getopt module. %%% @doc Example file for the getopt module.
%%% @end %%% @end
%%% %%%
Expand All @@ -9,9 +9,7 @@
%%% retrieved from: http://www.opensource.org/licenses/bsd-license.php %%% retrieved from: http://www.opensource.org/licenses/bsd-license.php
%%%------------------------------------------------------------------- %%%-------------------------------------------------------------------
-module(ex1). -module(ex1).
-author('Juan Jose Comellas <jcomellas@novamens.com>'). -author('juanjo@comellas.org').

-include("include/getopt.hrl").


-export([test/0, test/1]). -export([test/0, test/1]).


Expand All @@ -26,7 +24,7 @@ test(CmdLine) ->
"getopt:parse/2 returns:~n~n", [CmdLine]), "getopt:parse/2 returns:~n~n", [CmdLine]),
case getopt:parse(OptSpecList, CmdLine) of case getopt:parse(OptSpecList, CmdLine) of
{ok, {Options, NonOptArgs}} -> {ok, {Options, NonOptArgs}} ->
io:format("Options:~n ~p~nNon-option arguments:~n ~p~n", [Options, NonOptArgs]); io:format("Options:~n ~p~n~nNon-option arguments:~n ~p~n", [Options, NonOptArgs]);
{error, {Reason, Data}} -> {error, {Reason, Data}} ->
io:format("Error: ~s ~p~n~n", [Reason, Data]), io:format("Error: ~s ~p~n~n", [Reason, Data]),
getopt:usage(OptSpecList, "ex1") getopt:usage(OptSpecList, "ex1")
Expand All @@ -36,48 +34,13 @@ test(CmdLine) ->
option_spec() -> option_spec() ->
CurrentUser = os:getenv("USER"), CurrentUser = os:getenv("USER"),
[ [
#option{name = help, %% {Name, ShortOpt, LongOpt, ArgSpec, HelpMsg}
short = $?, {help, $?, "help", undefined, "Show the program options"},
long = "help", {username, $U, "username", string, "Username to connect to the database"},
help = "Show the program options" {password, $P, "password", {string, CurrentUser}, "Password to connect to the database"},
}, {host, $h, "host", {string, "localhost"}, "Database server host name or IP address"},
#option{name = username, {port, $p, "port", {integer, 1000}, "Database server port"},
short = $U, {output_file, $o, "output-file", string, "File where the data will be saved to"},
long = "username", {xml, $x, "xml", undefined, "Output data as XML"},
arg = string, {dbname, undefined, undefined, string, "Database name"}
help = "Username to connect to the database"
},
#option{name = password,
short = $P,
long = "password",
arg = {string, CurrentUser},
help = "Password to connect to the database"
},
#option{name = host,
short = $h,
long = "host",
arg = {string, "localhost"},
help = "Database server host name or IP address"
},
#option{name = port,
short = $p,
long = "port",
arg = {integer, 1000},
help = "Database server port"
},
#option{name = output_file,
short = $o,
long = "output-file",
arg = string,
help = "File where the data will be saved to"
},
#option{name = xml,
short = $x,
long = "xml",
help = "Output data as XML"
},
#option{name = dbname,
arg = string,
help = "Database name"
}
]. ].

0 comments on commit 4b03285

Please sign in to comment.