--
-- <summary>
-- This is a generic package implementing a simple-to-use command line
-- parser. Yes, I know, everyone makes his/her own command line parser...
-- so, I wrote mine. As they say, every open source project starts
-- with a programmer that schratches hes own itch. So I did... If
-- you find this useful, you are welcome to use it.
--
-- The ideas behind this package are the following
--
-- * Parameters are nominal, non positional. The syntax is of
-- "named parameter" type, that is, each command line parameter is
-- expected to have thefollowing format
--
-- label ['=' value]
--
-- where "label" is any string without '='.
--
-- * Parsed value are written in a "configuration variable" whose type
-- is a formal parameter of this package. The values are written
-- in the configuration variable by using some callbacks provided
-- by caller.
--
-- The names of the parameters are given to the parser in "parameter
-- description array" that is an array of records that specify
--
-- + The parameter name
--
-- + A default value (if needed)
--
-- + If the parameter is mandatory
--
-- + If it can be specified more than once
--
-- + The callback function to be called when the parameter is found
--
-- In order to parse the command line it suffices to call Parse_Command_Line
-- giving as argument the array of parameter descriptors and the configuration
-- variable to be written. For every parameter found, the corresponding
-- callback function is called. If at the end of the parsing there are some
-- optional parameters that were missing from the command line, the
-- corresponding callbacks are called with the default parameter.
-- </summary>
with Ada.Strings.Unbounded;
with Ada.Text_IO;
generic
type Config_Data is limited private;
-- The parameters read from the command line will be written in
-- a variable of this type
-- Set this to False if you want case insensitive option matching.
-- For example, if you set this to False, "input", "Input", "INPUT"
-- and "InPuT" will be equivalent names for the option "input"
Case_Sensitive : Boolean := True;
package Generic_Line_Parser is
use Ada.Strings.Unbounded;
type Parameter_Callback is
access procedure (Name : in Unbounded_String;
Value : in Unbounded_String;
Result : in out Config_Data);
type Parameter_Descriptor is
record
Name : Unbounded_String; -- Parameter name
Default : Unbounded_String; -- Default value used if not on C.L.
Mandatory : Boolean; -- Parameter MUST be given
Only_Once : Boolean; -- Parameter MUST NOT be given more than once
Callback : Parameter_Callback; -- Called when parameter found
end record;
-- <description>Record holding the description of a parameter. The fields
-- should be self-explenatory (I hope). The only field that needs some
-- explanation is Name since it allows to specify more than one
-- name for each parameter. The syntax is very simple: just separate
-- the names with commas. For example, if Name is "f,filename,input"
-- one can use on the command line, with the same effect f=/tmp/a.txt or
-- filename=/tmp/a.txt or input=/tmp/a.txt. Spaces at both ends of
-- the label name are trimmed, so that, for example, "f,filename,input"
-- is equivalent to "f , filename ,input "
-- </description>
type Parameter_Descriptor_Array is
array (Natural range <>) of Parameter_Descriptor;
-- Main exported method. It parses the command line and it writes
-- the result in Result. If some error is encountered, Bad_Command
-- is raised with an explicative exception message. Help_Line,
-- if not empty, is written to Help_Output in case of error.
procedure Parse_Command_Line
(Parameters : in Parameter_Descriptor_Array;
Result : out Config_Data;
Help_Line : in String := "";
Help_Output : in Ada.Text_IO.File_Type := Ada.Text_IO.Standard_Error);
Bad_Command : exception;
-- Convenient conversion function to Float that raise Bad_Command if
-- the argument has not a valid syntax
function To_Float (X : Unbounded_String)
return Float;
-- Convenient conversion function to Float that raise Bad_Command if
-- the argument has not a valid syntax
function To_Natural (X : Unbounded_String)
return Natural;
end Generic_Line_Parser;