1/*============================================================================
2  KWSys - Kitware System Library
3  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
4
5  Distributed under the OSI-approved BSD License (the "License");
6  see accompanying file Copyright.txt for details.
7
8  This software is distributed WITHOUT ANY WARRANTY; without even the
9  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10  See the License for more information.
11============================================================================*/
12#ifndef @KWSYS_NAMESPACE@_CommandLineArguments_hxx
13#define @KWSYS_NAMESPACE@_CommandLineArguments_hxx
14
15#include <@KWSYS_NAMESPACE@/Configure.h>
16#include <@KWSYS_NAMESPACE@/Configure.hxx>
17
18#include <@KWSYS_NAMESPACE@/stl/string>
19#include <@KWSYS_NAMESPACE@/stl/vector>
20
21/* Define this macro temporarily to keep the code readable.  */
22#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
23# define kwsys_stl @KWSYS_NAMESPACE@_stl
24#endif
25
26namespace @KWSYS_NAMESPACE@
27{
28
29class CommandLineArgumentsInternal;
30struct CommandLineArgumentsCallbackStructure;
31
32/** \class CommandLineArguments
33 * \brief Command line arguments processing code.
34 *
35 * Find specified arguments with optional options and execute specified methods
36 * or set given variables.
37 *
38 * The two interfaces it knows are callback based and variable based. For
39 * callback based, you have to register callback for particular argument using
40 * AddCallback method. When that argument is passed, the callback will be
41 * called with argument, value, and call data. For boolean (NO_ARGUMENT)
42 * arguments, the value is "1". If the callback returns 0 the argument parsing
43 * will stop with an error.
44 *
45 * For the variable interface you associate variable with each argument. When
46 * the argument is specified, the variable is set to the specified value casted
47 * to the appropriate type. For boolean (NO_ARGUMENT), the value is "1".
48 *
49 * Both interfaces can be used at the same time.
50 *
51 * Possible argument types are:
52 *   NO_ARGUMENT     - The argument takes no value             : --A
53 *   CONCAT_ARGUMENT - The argument takes value after no space : --Aval
54 *   SPACE_ARGUMENT  - The argument takes value after space    : --A val
55 *   EQUAL_ARGUMENT  - The argument takes value after equal    : --A=val
56 *   MULTI_ARGUMENT  - The argument takes values after space   : --A val1 val2 val3 ...
57 *
58 * Example use:
59 *
60 * kwsys::CommandLineArguments arg;
61 * arg.Initialize(argc, argv);
62 * typedef kwsys::CommandLineArguments argT;
63 * arg.AddArgument("--something", argT::EQUAL_ARGUMENT, &some_variable,
64 *                 "This is help string for --something");
65 * if ( !arg.Parse() )
66 *   {
67 *   kwsys_ios::cerr << "Problem parsing arguments" << kwsys_ios::endl;
68 *   res = 1;
69 *   }
70 *
71 */
72
73class @KWSYS_NAMESPACE@_EXPORT CommandLineArguments
74{
75public:
76  CommandLineArguments();
77  ~CommandLineArguments();
78
79  /**
80   * Various argument types.
81   */
82  enum ArgumentTypeEnum {
83    NO_ARGUMENT,
84    CONCAT_ARGUMENT,
85    SPACE_ARGUMENT,
86    EQUAL_ARGUMENT,
87    MULTI_ARGUMENT
88  };
89
90  /**
91   * Various variable types. When using the variable interface, this specifies
92   * what type the variable is.
93   */
94  enum VariableTypeEnum {
95    NO_VARIABLE_TYPE = 0, // The variable is not specified
96    INT_TYPE,             // The variable is integer (int)
97    BOOL_TYPE,            // The variable is boolean (bool)
98    DOUBLE_TYPE,          // The variable is float (double)
99    STRING_TYPE,          // The variable is string (char*)
100    STL_STRING_TYPE,      // The variable is string (char*)
101    VECTOR_INT_TYPE,             // The variable is integer (int)
102    VECTOR_BOOL_TYPE,            // The variable is boolean (bool)
103    VECTOR_DOUBLE_TYPE,          // The variable is float (double)
104    VECTOR_STRING_TYPE,          // The variable is string (char*)
105    VECTOR_STL_STRING_TYPE,      // The variable is string (char*)
106    LAST_VARIABLE_TYPE
107  };
108
109  /**
110   * Prototypes for callbacks for callback interface.
111   */
112  typedef int(*CallbackType)(const char* argument, const char* value,
113    void* call_data);
114  typedef int(*ErrorCallbackType)(const char* argument, void* client_data);
115
116  /**
117   * Initialize internal data structures. This should be called before parsing.
118   */
119  void Initialize(int argc, const char* const argv[]);
120  void Initialize(int argc, char* argv[]);
121
122  /**
123   * Initialize internal data structure and pass arguments one by one. This is
124   * convenience method for use from scripting languages where argc and argv
125   * are not available.
126   */
127  void Initialize();
128  void ProcessArgument(const char* arg);
129
130  /**
131   * This method will parse arguments and call appropriate methods.
132   */
133  int Parse();
134
135  /**
136   * This method will add a callback for a specific argument. The arguments to
137   * it are argument, argument type, callback method, and call data. The
138   * argument help specifies the help string used with this option. The
139   * callback and call_data can be skipped.
140   */
141  void AddCallback(const char* argument, ArgumentTypeEnum type,
142    CallbackType callback, void* call_data, const char* help);
143
144  /**
145   * Add handler for argument which is going to set the variable to the
146   * specified value. If the argument is specified, the option is casted to the
147   * appropriate type.
148   */
149  void AddArgument(const char* argument, ArgumentTypeEnum type,
150    bool* variable, const char* help);
151  void AddArgument(const char* argument, ArgumentTypeEnum type,
152    int* variable, const char* help);
153  void AddArgument(const char* argument, ArgumentTypeEnum type,
154    double* variable, const char* help);
155  void AddArgument(const char* argument, ArgumentTypeEnum type,
156    char** variable, const char* help);
157  void AddArgument(const char* argument, ArgumentTypeEnum type,
158    kwsys_stl::string* variable, const char* help);
159
160  /**
161   * Add handler for argument which is going to set the variable to the
162   * specified value. If the argument is specified, the option is casted to the
163   * appropriate type. This will handle the multi argument values.
164   */
165  void AddArgument(const char* argument, ArgumentTypeEnum type,
166    kwsys_stl::vector<bool>* variable, const char* help);
167  void AddArgument(const char* argument, ArgumentTypeEnum type,
168    kwsys_stl::vector<int>* variable, const char* help);
169  void AddArgument(const char* argument, ArgumentTypeEnum type,
170    kwsys_stl::vector<double>* variable, const char* help);
171  void AddArgument(const char* argument, ArgumentTypeEnum type,
172    kwsys_stl::vector<char*>* variable, const char* help);
173  void AddArgument(const char* argument, ArgumentTypeEnum type,
174    kwsys_stl::vector<kwsys_stl::string>* variable, const char* help);
175
176  /**
177   * Add handler for boolean argument. The argument does not take any option
178   * and if it is specified, the value of the variable is true/1, otherwise it
179   * is false/0.
180   */
181  void AddBooleanArgument(const char* argument,
182    bool* variable, const char* help);
183  void AddBooleanArgument(const char* argument,
184    int* variable, const char* help);
185  void AddBooleanArgument(const char* argument,
186    double* variable, const char* help);
187  void AddBooleanArgument(const char* argument,
188    char** variable, const char* help);
189  void AddBooleanArgument(const char* argument,
190    kwsys_stl::string* variable, const char* help);
191
192  /**
193   * Set the callbacks for error handling.
194   */
195  void SetClientData(void* client_data);
196  void SetUnknownArgumentCallback(ErrorCallbackType callback);
197
198  /**
199   * Get remaining arguments. It allocates space for argv, so you have to call
200   * delete[] on it.
201   */
202  void GetRemainingArguments(int* argc, char*** argv);
203  void DeleteRemainingArguments(int argc, char*** argv);
204
205  /**
206   * If StoreUnusedArguments is set to true, then all unknown arguments will be
207   * stored and the user can access the modified argc, argv without known
208   * arguments.
209   */
210  void StoreUnusedArguments(bool val) { this->StoreUnusedArgumentsFlag = val; }
211  void GetUnusedArguments(int* argc, char*** argv);
212
213  /**
214   * Return string containing help. If the argument is specified, only return
215   * help for that argument.
216   */
217  const char* GetHelp() { return this->Help.c_str(); }
218  const char* GetHelp(const char* arg);
219
220  /**
221   * Get / Set the help line length. This length is used when generating the
222   * help page. Default length is 80.
223   */
224  void SetLineLength(unsigned int);
225  unsigned int GetLineLength();
226
227  /**
228   * Get the executable name (argv0). This is only available when using
229   * Initialize with argc/argv.
230   */
231  const char* GetArgv0();
232
233  /**
234   * Get index of the last argument parsed. This is the last argument that was
235   * parsed ok in the original argc/argv list.
236   */
237  unsigned int GetLastArgument();
238
239protected:
240  void GenerateHelp();
241
242  //! This is internal method that registers variable with argument
243  void AddArgument(const char* argument, ArgumentTypeEnum type,
244    VariableTypeEnum vtype, void* variable, const char* help);
245
246  bool GetMatchedArguments(kwsys_stl::vector<kwsys_stl::string>* matches,
247    const kwsys_stl::string& arg);
248
249  //! Populate individual variables
250  bool PopulateVariable(CommandLineArgumentsCallbackStructure* cs,
251    const char* value);
252
253  //! Populate individual variables of type ...
254  void PopulateVariable(bool* variable, const kwsys_stl::string& value);
255  void PopulateVariable(int* variable, const kwsys_stl::string& value);
256  void PopulateVariable(double* variable, const kwsys_stl::string& value);
257  void PopulateVariable(char** variable, const kwsys_stl::string& value);
258  void PopulateVariable(kwsys_stl::string* variable, const kwsys_stl::string& value);
259  void PopulateVariable(kwsys_stl::vector<bool>* variable, const kwsys_stl::string& value);
260  void PopulateVariable(kwsys_stl::vector<int>* variable, const kwsys_stl::string& value);
261  void PopulateVariable(kwsys_stl::vector<double>* variable, const kwsys_stl::string& value);
262  void PopulateVariable(kwsys_stl::vector<char*>* variable, const kwsys_stl::string& value);
263  void PopulateVariable(kwsys_stl::vector<kwsys_stl::string>* variable, const kwsys_stl::string& value);
264
265  typedef CommandLineArgumentsInternal Internal;
266  Internal* Internals;
267  kwsys_stl::string Help;
268
269  unsigned int LineLength;
270
271  bool StoreUnusedArgumentsFlag;
272};
273
274} // namespace @KWSYS_NAMESPACE@
275
276/* Undefine temporary macro.  */
277#if !defined (KWSYS_NAMESPACE) && !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
278# undef kwsys_stl
279#endif
280
281#endif
282
283
284
285
286
287