| // Copyright (C) 2001-2010 Gianni Mariani |
| // |
| // This program is free software; you can redistribute it and/or modify |
| // it under the terms of the GNU General Public License as published by |
| // the Free Software Foundation; either version 2 of the License, or |
| // (at your option) any later version. |
| // |
| // This program is distributed in the hope that it 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 |
| // along with this program; if not, write to the Free Software |
| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| // |
| // As a special exception, you may use this file as part of a free software |
| // library without restriction. Specifically, if other files instantiate |
| // templates or use macros or inline functions from this file, or you compile |
| // this file and link it with other files to produce an executable, this |
| // file 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 General Public License. |
| // |
| // This exception applies only to the code released under the name GNU |
| // Common C++. If you copy code from other releases into a copy of GNU |
| // Common C++, as the General Public License permits, the exception does |
| // not apply to the code that you add in this way. To avoid misleading |
| // anyone as to the status of such modified files, you must delete |
| // this exception notice from them. |
| // |
| // If you write modifications of your own for GNU Common C++, it is your choice |
| // whether to permit this exception to apply to your modifications. |
| // If you do not wish that, delete this exception notice. |
| // |
| |
| /** |
| * @file cmdoptns.h |
| * @short Command line option parsing interface. |
| **/ |
| |
| #ifndef CCXX_CMDOPTNS_H_ |
| #define CCXX_CMDOPTNS_H_ |
| |
| #ifndef CCXX_STRING_H_ |
| #include <cc++/string.h> |
| #endif |
| |
| #ifdef CCXX_NAMESPACES |
| namespace ost { |
| #endif |
| |
| class CommandOption; |
| class CommandOptionParse; |
| |
| /** |
| * This defines a linked list head pointer for all the command line |
| * options that use the default list. It will most likely |
| * be used in most cases without being explicitly referenced in application |
| * code. It is a default value of various method's parameters. |
| * |
| */ |
| extern __EXPORT CommandOption * defaultCommandOptionList; |
| |
| /** |
| * CommandOption is the base class for all command line options. Command |
| * line options can be defined statically and used when constructing |
| * a command line parser onject using makeCommandOptionParse. This serves |
| * only as a base class to CommandOptionWithArg, CommandOptionRest or |
| * CommandOptionNoArg which can also be used to derive more complex |
| * classes or even entire applications. |
| * |
| * @author Gianni Mariani <gianni@mariani.ws> |
| */ |
| class __EXPORT CommandOption { |
| public: |
| |
| /** |
| * Long option name, these will be preceded with "--" on the command line. |
| * e.g. --file foo.x |
| */ |
| const char * optionName; |
| |
| /** |
| * option letter, these will be preceded with "-" on the command line. |
| * e.g. -f foo.x |
| */ |
| const char * optionLetter; |
| |
| /** |
| * A short description of the option for Usage messages. |
| * e.g. Usage: mycommand : blah |
| * -f, --file \<DESCRIPTION here\> |
| */ |
| const char * description; |
| |
| /** |
| * OptionType is for denoting what type of option this is, with an |
| * arg, without an arg or the trailing args. |
| * @short Option type |
| */ |
| enum OptionType { |
| /** |
| * This option is associated with a value |
| */ |
| hasArg, |
| /** |
| * This option is a flag only |
| */ |
| noArg, |
| /** |
| * Remaining of the command line arguments |
| */ |
| trailing, |
| /** |
| * Collect values that are not a value to an option |
| */ |
| collect |
| }; |
| |
| /** |
| * This command option's OptionType. |
| */ |
| OptionType optionType; // HasArg, NoArg or Trailing |
| |
| /** |
| * True if this parameter is required. If the parameter is not supplied |
| * and required is true, an error will be flagged in the option processor. |
| */ |
| bool required; // Option is required - fail without it |
| |
| /** |
| * This next CommandOption in this list of options or nil if no more |
| * options exist. |
| */ |
| CommandOption * next; |
| |
| /** |
| * A virtual destructor just in case. |
| */ |
| virtual ~CommandOption(); |
| |
| /** |
| * CommandOption contructor. Note the default values for required and |
| * ppNext. |
| * |
| * @param inOptionName long option name |
| * @param inOptionLetter short letter name |
| * @param inDescription short description of the option |
| * @param inOptionType the type of this option |
| * @param inRequired true if option is required |
| * @param ppNext the linked list header |
| */ |
| CommandOption( |
| const char * inOptionName, |
| const char * inOptionLetter, |
| const char * inDescription, |
| OptionType inOptionType, |
| bool inRequired = false, |
| CommandOption ** ppNext = & defaultCommandOptionList |
| ); |
| |
| /** |
| * foundOption is called by the CommandOptionParse object during the parsing |
| * of the command line options. |
| * |
| * @param cop pointer to the command option parser |
| * @param value the value of this option |
| */ |
| virtual void foundOption( CommandOptionParse * cop, const char * value = 0 ); |
| |
| /** |
| * foundOption is called by the CommandOptionParse object during the parsing |
| * of the command line options. |
| * |
| * @param cop pointer to the command option parser |
| * @param value an array of values of this option |
| * @param num number of values in the array |
| */ |
| virtual void foundOption( CommandOptionParse * cop, const char ** value, int num ); |
| |
| /** |
| * Once parsing of command line options is complete, this method is called. |
| * This can be used to perform last minute checks on the options collected. |
| * |
| * @param cop pointer to the command option parser |
| */ |
| virtual void parseDone( CommandOptionParse * cop ); |
| |
| /** |
| * Once CommandOption objects have completed parsing and there are no |
| * errors they may have some specific tasks to perform. PerformTask |
| * must return. |
| * |
| * @param cop pointer to the command option parser |
| */ |
| virtual void performTask( CommandOptionParse * cop ); |
| |
| /** |
| * For fields with the required flag set, this method is used to determine |
| * if the Option has satisfied it's required status. The default methods |
| * simply returns true if any values have been found. This could be specialized |
| * to return true based on some other criteria. |
| */ |
| virtual bool hasValue(); |
| |
| }; |
| |
| /** |
| * Derived class of CommandOption for options that have a value associated with them. |
| * Classes CommandOptionRest and CommandOptionArg derive from this class. |
| */ |
| class __EXPORT CommandOptionWithArg : public CommandOption { |
| public: |
| |
| /** |
| * Array of list of values collected for this option. |
| */ |
| const char ** values; |
| |
| /** |
| * Number of values in the values array. |
| */ |
| int numValue; |
| |
| /** |
| * CommandOptionWithArg contructor. Note the default values for required and |
| * ppNext. |
| * |
| * @param inOptionName long option name |
| * @param inOptionLetter short letter name |
| * @param inDescription short description of the option |
| * @param inOptionType the type of this option |
| * @param inRequired true if option is required |
| * @param ppNext the linked list header |
| */ |
| CommandOptionWithArg( |
| const char * inOptionName, |
| const char * inOptionLetter, |
| const char * inDescription, |
| OptionType inOptionType, |
| bool inRequired = false, |
| CommandOption ** ppNext = & defaultCommandOptionList |
| ); |
| |
| virtual ~CommandOptionWithArg(); |
| |
| virtual void foundOption( CommandOptionParse * cop, const char * value = 0 ); |
| virtual void foundOption( CommandOptionParse * cop, const char ** value, int num ); |
| virtual bool hasValue(); |
| }; |
| |
| /** |
| * Class for options with an argument e.g. --option value . |
| */ |
| class __EXPORT CommandOptionArg : public CommandOptionWithArg { |
| public: |
| |
| /** |
| * CommandOptionArg contructor. This sets the optionType for this |
| * object to HasArg. |
| * |
| * @param inOptionName long option name |
| * @param inOptionLetter short letter name |
| * @param inDescription short description of the option |
| * @param inRequired true if option is required |
| * @param ppNext the linked list header |
| */ |
| CommandOptionArg( |
| const char * inOptionName, |
| const char * inOptionLetter, |
| const char * inDescription, |
| bool inRequired = false, |
| CommandOption ** ppNext = & defaultCommandOptionList |
| ); |
| |
| virtual ~CommandOptionArg(); |
| |
| |
| }; |
| |
| /** |
| * It only makes sense to have a single one of these set and it is |
| * exclusive with CommandOptionCollect. It is the option that takes the rest |
| * of the command line options that are not part of any other options. |
| * e.g. "strace -ofile command arg1 arg2". The "command arg1 arg2" part is |
| * placed in objects of this class. |
| * |
| * @short CommandOption to take the rest of the command line |
| */ |
| class __EXPORT CommandOptionRest : public CommandOptionWithArg { |
| public: |
| |
| /** |
| * CommandOptionRest contructor. This sets the optionType for this |
| * object to Trailing. |
| * |
| * @param inOptionName long option name |
| * @param inOptionLetter short letter name |
| * @param inDescription short description of the option |
| * @param inRequired true if option is required |
| * @param ppNext the linked list header |
| */ |
| CommandOptionRest( |
| const char * inOptionName, |
| const char * inOptionLetter, |
| const char * inDescription, |
| bool inRequired = false, |
| CommandOption ** ppNext = & defaultCommandOptionList |
| ); |
| |
| }; |
| |
| /** |
| * It only makes sense to have a single one of these set and it is also |
| * exclusive with CommandOptionRest. This makes parameter collecting |
| * behave line the Unix "cat" command. |
| * |
| * @short CommandOption to collect parameters that are not options. |
| */ |
| class __EXPORT CommandOptionCollect : public CommandOptionWithArg { |
| public: |
| |
| /** |
| * CommandOptionRest contructor. This sets the optionType for this |
| * object to Collect. |
| * |
| * @param inOptionName long option name |
| * @param inOptionLetter short letter name |
| * @param inDescription short description of the option |
| * @param inRequired true if option is required |
| * @param ppNext the linked list header |
| */ |
| CommandOptionCollect( |
| const char * inOptionName, |
| const char * inOptionLetter, |
| const char * inDescription, |
| bool inRequired = false, |
| CommandOption ** ppNext = & defaultCommandOptionList |
| ); |
| |
| }; |
| |
| /** |
| * CommandOption type for flags. |
| */ |
| class __EXPORT CommandOptionNoArg : public CommandOption { |
| public: |
| |
| /** |
| * The number of times this value has been set. |
| */ |
| int numSet; // The number of times this argument is set |
| |
| /** |
| * CommandOptionArg contructor. This sets the optionType for this |
| * object to NoArg. |
| * |
| * @param inOptionName long option name |
| * @param inOptionLetter short letter name |
| * @param inDescription short description of the option |
| * @param inRequired true if option is required |
| * @param ppNext the linked list header |
| */ |
| CommandOptionNoArg( |
| const char * inOptionName, |
| const char * inOptionLetter, |
| const char * inDescription, |
| bool inRequired = false, |
| CommandOption ** ppNext = & defaultCommandOptionList |
| ); |
| |
| /** |
| * CommandOptionNoArg::foundOption will evpect a nil "value" passed in. |
| */ |
| virtual void foundOption( CommandOptionParse * cop, const char * value = 0 ); |
| |
| }; |
| |
| /** |
| * This is the CommandOptionParse interface class. To implement this object you can |
| * call makeCommandOptionParse(); This will instantiate a dynamically allocated |
| * version of this class and parse the command line for the list of command options |
| * that are passed in. |
| * |
| * @author Gianni Mariani <gianni@mariani.ws> |
| */ |
| |
| class __EXPORT CommandOptionParse { |
| public: |
| |
| /** |
| * Virtual destructor needed so that the object may be correctly deleted. |
| */ |
| virtual ~CommandOptionParse() = 0; |
| |
| /** |
| * Get the value of the error flag set if the parser encountered errors. |
| */ |
| virtual bool argsHaveError() = 0; |
| |
| /** |
| * Return a string of text describing the list of errors encountered. |
| */ |
| virtual const char * printErrors() = 0; |
| |
| /** |
| * Return a string that contains the usage description of this list of paramaters. |
| */ |
| virtual const char * printUsage() = 0; |
| |
| /** |
| * Register an error with this parser. This string will be appended to the |
| * errors already buffered in this object. |
| */ |
| virtual void registerError( const char * errMsg ) = 0; |
| |
| /** |
| * The method should be invoked by the main code once it has determined that |
| * the application should be started. |
| */ |
| virtual void performTask() = 0; |
| |
| }; |
| |
| /** |
| * makeCommandOptionParse will create an implementation of a CommandOptionParse |
| * object. This particular implementation is a wrapper around getopt_long(3). |
| * That interface unfortunatly does not provide enough information to give |
| * the best error messages with malformed input. If the implementation changes |
| * there is a good chance that the binary interface will remain the same. |
| * |
| */ |
| __EXPORT CommandOptionParse * makeCommandOptionParse( |
| int argc, |
| char ** argv, |
| const char * comment, |
| CommandOption * options = defaultCommandOptionList |
| ); |
| |
| #ifdef CCXX_NAMESPACES |
| } |
| #endif |
| |
| #endif |
| |
| /** EMACS ** |
| * Local variables: |
| * mode: c++ |
| * c-basic-offset: 4 |
| * End: |
| */ |
| |