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