------------------------------------------------------------------------ -- -- -- McKae Software Utilities -- -- -- -- Copyright (C) 2003 McKae Technologies -- -- -- -- The McKae software utilities are free software; you can -- -- redistribute it and/or modify it under terms of the GNU General -- -- Public License as published by the Free Software Foundation; -- -- either version 2, or (at your option) any later version. McKae -- -- Software Utilities are distributed in the hope that they will be -- -- useful, but WITHOUT ANY WARRANTY; without even the implied -- -- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- -- See the GNU General Public License for more details. You should -- -- have received a copy of the GNU General Public License distributed -- -- with DTraq; see file COPYING. If not, write to the Free Software -- -- Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, -- -- USA. -- -- -- -- As a special exception, if other files instantiate generics from -- -- this unit, or you link this unit with other files to produce an -- -- executable, this unit does not by itself cause the resulting -- -- executable to be covered by the GNU General Public License. This -- -- exception does not however invalidate any other reasons why the -- -- executable file might be covered by the GNU Public License. -- -- -- -- The McKae Software Utilities are maintained by McKae Technologies -- -- (http://www.mckae.com). -- ------------------------------------------------------------------------ with Ada.Strings.Bounded; generic type Command_Line_Components is (<>); -- The discrete type to which options correspond. Max_Options : Natural := 100; -- This should be altered only if an excessive number of options -- are required. Max_Option_Length : Positive := 20; -- If options may take the form of strings, this is the maximum -- length of such a string. Max_Argument_Length : Positive := 255; -- The maximum length of an argument. Option_Designation : String := "-"; -- Character(s) designating an option string. Add to or modify as -- needed. Note: "+-" are commonly used option designators to signify -- options that can be turned on or off. package Mckae.Environment.Command_Line_Processor is ----------------------------------------------------------------------- -- -- Name: Command_Line_Processor -- Author: Marc A. Criley -- Date: 06 May 1996 -- -- Abstract: Associate command line options to members of an application- -- defined scalar type, along with providing simple access to arguments. -- Supports case (in)sensitivity, option arguments, and configurable option -- designator(s), usage description, and error handling. -- -- Contact: mcriley@acm.org -- -- This software may be freely distributed. ----------------------------------------------------------------------- -- -- Usage (see simple_cli.adb for a working example): -- -- 1) Define a scalar type with which command line options will be -- associated. -- -- 2) Instantiate this package, supplying that type and specifying any other -- applicable settings accessible in the generic parameters. -- -- 3a) Declare a variable or constant of type Command_Line_Item_Mappings -- with the initializing aggregate that will implicitly supply the index -- range for the array, or, -- -- 3b) Declare a variable of type Command_Line_Item_Mappings, specifying an -- index range corresponding to the number of options that will be -- recognized and, optionally, an initializing aggregate. -- -- 4) Supply values for the initializing aggregate (or if an initializing -- aggregate was not used, initialize the variable in the body of the code) -- by calling the Set_Option function for each of the options to be -- recognized. Specify the member of the "option type" to be associated with -- a command line option, the option character or string, whether -- recognizing that option is case sensitive, and whether the option -- requires an argument. Note that more than one option representation can -- be associated with the same member of the option type. -- -- 5) Install the command line item mapping by calling -- Install_Option_Mappings with the variable or constant. -- -- 6) Set any special USAGE or error handling by calling the appropriate -- procedures. -- -- 7) In the body of the application where the command line options and -- arguments are processed, set up a loop in which Next_Item is called in -- each iteration. -- -- 8) Process the response from each call to Next_Item. Next_Item returns an -- object of type Command_Line_Items, the discriminant of which, Item_Kind, -- indicates whether an option or argument is being returned, if help was -- requested, if an error occurred, or if all command line items have been -- processed. See the definition of Command_Line_Items regarding the format -- of the data it returns. -- ----------------------------------------------------------------------- -- -- These types and subprograms implement the mapping between option -- identifiers and the corresponding type members. -- type Item_Mappings is private; type Command_Line_Item_Mappings is array (Natural range <>) of Item_Mappings; -- Associate a member item of the type defining the command line options -- with the character indicating that option. Set Case_Sensitive as -- appropriate and Argumentable if the option requires an argument. function Set_Option (Item : Command_Line_Components; Identifier : Character; Case_Sensitive : Boolean := True; Argumented : Boolean := False) return Item_Mappings; -- As above, but with an identifier string being associated with the option. function Set_Option (Item : Command_Line_Components; Identifier : String; Case_Sensitive : Boolean := True; Argumented : Boolean := False) return Item_Mappings; -- Install the mapping. Successive calls to this procedure replace previous -- mappings. If there is a problem during installation, the -- Option_Specification_Error exception is raised. procedure Install_Option_Mappings (Mappings : Command_Line_Item_Mappings); Option_Specification_Error : exception; -- Raised if there is a problem setting up an option configuration or -- installing it. This would be raised by mapping the same option -- identifier to two different option type members, or if one letter case of -- an option was specified as case-sensitive and the other as -- case-insensitive, if the length of an option string exceeded the -- Max_Option_Length, or if more than Max_Options were defined. ----------------------------------------------------------------------- -- -- The following procedures adjust the command line processor's interaction -- with users. -- ----------------------------------------------------------------------- ----------------------------------------------------------------------- -- -- The Set_Usage procedures permit supplying either a string specifying the -- program's proper usage profile (which is the default action), or a -- parameterless procedure for more extensive interaction. The string is -- displayed, or the usage procedure invoked, upon encountering the option -- "-h", "-help", or "-?"; or the single argument "help" or "?". -- ----------------------------------------------------------------------- procedure Set_Usage (Usage_String : String := "USAGE: No information."); type Usage_Procedure_Profile is access procedure; procedure Set_Usage (Usage_Procedure : Usage_Procedure_Profile); ----------------------------------------------------------------------- -- -- Set_Invalid_Options_Message and Set_Omitted_Argument_Message permit the -- specification of a message appropriate to encountering invalid options or -- finding that no argument was supplied for an option that requires one. -- To specify that no message at all is to be supplied for errors, invoke -- this procedure with a null string as the Error_Message. -- -- Normally, processing of the command line ends after encountering an -- error. To continue, as in the case when unrecognized options are to -- be passed on to another program, call Ignore_Unrecognized_Options. -- When an unrecognized option is encountered, no further processing -- within that block of options will occur, processing will resume with -- the subsequent block. Upon encountering an unrecognized option, -- Next_Item (see below) will return CLI_Error and the Unknown_Option -- field will contain that entire option block, even if some of the -- initial characters did correspond to recognized options. PROCEED -- WITH CAUTION AFTER TURNING OFF OPTION ERROR RECOGNITION. -- ----------------------------------------------------------------------- procedure Set_Invalid_Options_Message (Error_Message : String := "Unrecognized option(s)"; Display_Usage : Boolean := True); procedure Ignore_Unrecognized_Options (Ignore : Boolean := True); procedure Set_Omitted_Argument_Message (Error_Message : String := "Missing argument"; Display_Usage : Boolean := True); ----------------------------------------------------------------------- -- -- The following type declarations define the format in which the -- options and arguments are returned to the calling routine. -- -- Arguments, supplied as such or as an argument associated with an -- option, are stored as a Bounded_Strings whose maximum length may be -- adjusted during instantiation. -- -- The Command_Line_Item_Kinds indicates what is being returned to the -- caller: -- 'CLI_Option' is accompanied by the value of the Command_Line_Components -- type corresponding to that option. If the option has been -- designated as one which itself has an argument, that argument -- is returned as well. -- -- 'CLI_Argument' returns a bounded string containing the argument. -- -- 'CLI_Help_Requested' indicates that usage help was requested, so it is -- likely that the application should simply exit. -- -- 'CLI_Complete' indicates there are no further options or arguments, -- including indicating that none were supplied at all. -- -- 'CLI_Option_Error' is returned when a supplied option is unrecognized. -- The unrecognized option is returned as well. -- Immediately prior to returning this result, the displaying of -- the invalid options message is triggered. -- ----------------------------------------------------------------------- package Argument_Strings is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => Max_Argument_Length); package Option_Strings is new Ada.Strings.Bounded.Generic_Bounded_Length (Max => Max_Option_Length); type Command_Line_Item_Kinds is (CLI_Option, CLI_Argument, CLI_Help_Requested, CLI_Complete, CLI_Option_Error); type Command_Line_Items (Item_Kind : Command_Line_Item_Kinds := CLI_Complete) is record case Item_Kind is when CLI_Option => Option : Command_Line_Components; Option_Argument : Argument_Strings.Bounded_String; Option_Designator : Character; -- The Option_Designator is the character preceding the -- option block. As such, it will take on only those -- values supplied by the Option_Designation parameter. when CLI_Argument => Argument : Argument_Strings.Bounded_String; when CLI_Help_Requested | CLI_Complete => null; when CLI_Option_Error => Unknown_Option : Option_Strings.Bounded_String; Unknown_Option_Designator : Character; end case; end record; ----------------------------------------------------------------------- -- -- These functions return the components of the command line invocation. -- ----------------------------------------------------------------------- -- Returns a value corresponding to the name of the program. function Command_Name return String; -- Returns the next option or argument supplied on the command line. -- Options and arguments may be specified in any order on the command line, -- although whatever follows an option that requires an argument is taken to -- be the argument. function Next_Item return Command_Line_Items; -- Return the entire command line as submitted to the application function Command_Line return String; ----------------------------------------------------------------------- private type Item_Mappings is record Item : Command_Line_Components; Identifier : Option_Strings.Bounded_String; Case_Sensitive : Boolean := True; Argumented : Boolean := False; end record; end Mckae.Environment.Command_Line_Processor;