ctkCommandLineParser.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. #ifndef __ctkCommandLineParser_h
  2. #define __ctkCommandLineParser_h
  3. // Qt includes
  4. #include <QString>
  5. #include <QStringList>
  6. #include <QVariant>
  7. class QSettings;
  8. // CTK includes
  9. #include "ctkCoreExport.h"
  10. /**
  11. * \ingroup Core
  12. *
  13. * The CTK command line parser.
  14. *
  15. * Use this class to add information about the command line arguments
  16. * your program understands and to easily parse them from a given list
  17. * of strings.
  18. *
  19. * This parser provides the following features:
  20. *
  21. * <ul>
  22. * <li>Add arguments by supplying a long name and/or a short name.
  23. * Arguments are validated using a regular expression. They can have
  24. * a default value and a help string.</li>
  25. * <li>Deprecated arguments.</li>
  26. * <li>Custom regular expressions for argument validation.</li>
  27. * <li>Set different argument name prefixes for native platform look and feel.</li>
  28. * <li>QSettings support. Default values for arguments can be read from
  29. * a QSettings object.</li>
  30. * <li>Create a help text for the command line arguments with support for
  31. * grouping arguments.</li>
  32. * </ul>
  33. *
  34. * Here is an example how to use this class inside a main function:
  35. *
  36. * \code
  37. * #include <ctkCommandLineParser.h>
  38. * #include <QCoreApplication>
  39. * #include <QTextStream>
  40. *
  41. * int main(int argc, char** argv)
  42. * {
  43. * QCoreApplication app(argc, argv);
  44. * // This is used by QSettings
  45. * QCoreApplication::setOrganizationName("MyOrg");
  46. * QCoreApplication::setApplicationName("MyApp");
  47. *
  48. * ctkCommandLineParser parser;
  49. * // Use Unix-style argument names
  50. * parser.setArgumentPrefix("--", "-");
  51. * // Enable QSettings support
  52. * parser.enableSettings("disable-settings");
  53. *
  54. * // Add command line argument names
  55. * parser.addArgument("disable-settings", "", QVariant::Bool, "Do not use QSettings");
  56. * parser.addArgument("help", "h", QVariant::Bool, "Show this help text");
  57. * parser.addArgument("search-paths", "s", QVariant::StringList, "A list of paths to search");
  58. *
  59. * // Parse the command line arguments
  60. * bool ok = false;
  61. * QHash<QString, QVariant> parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok);
  62. * if (!ok)
  63. * {
  64. * QTextStream(stderr, QIODevice::WriteOnly) << "Error parsing arguments: "
  65. * << parser.errorString() << "\n";
  66. * return EXIT_FAILURE;
  67. * }
  68. *
  69. * // Show a help message
  70. * if (parsedArgs.contains("help") || parsedArgs.contains("h"))
  71. * {
  72. * QTextStream(stdout, QIODevice::WriteOnly) << parser.helpText();
  73. * return EXIT_SUCCESS;
  74. * }
  75. *
  76. * // Do something
  77. *
  78. * return EXIT_SUCCESS;
  79. * }
  80. * \endcode
  81. */
  82. class CTK_CORE_EXPORT ctkCommandLineParser : public QObject
  83. {
  84. Q_OBJECT
  85. Q_PROPERTY(QString errorString READ errorString)
  86. Q_PROPERTY(QStringList unparsedArguments READ unparsedArguments)
  87. Q_PROPERTY(bool settingsEnabled READ settingsEnabled)
  88. public:
  89. typedef QObject Superclass;
  90. /**
  91. * Constructs a parser instance.
  92. *
  93. * If QSettings support is enabled by a call to <code>enableSettings()</code>
  94. * a default constructed QSettings instance will be used when parsing
  95. * the command line arguments. Make sure to call <code>QCoreApplication::setOrganizationName()</code>
  96. * and <code>QCoreApplication::setApplicationName()</code> before using default
  97. * constructed QSettings objects.
  98. *
  99. * @param newParent The QObject parent.
  100. */
  101. ctkCommandLineParser(QObject* newParent = 0);
  102. /**
  103. * Constructs a parser instance.
  104. *
  105. * If QSettings support is enabled by a call to <code>enableSettings()</code>
  106. * the provided QSettings instance will be used. If the QSettings instance is
  107. * zero, a default constructed QSettings instance will be used when parsing
  108. * the command line arguments. Using a default constructed instance is usually
  109. * what you want, if you have called <code>QCoreApplication::setOrganizationName()</code>
  110. * and <code>QCoreApplication::setApplicationName()</code>.
  111. *
  112. * @param settings A QSettings instance which should be used.
  113. * @param newParent The QObject parent.
  114. *
  115. *
  116. */
  117. ctkCommandLineParser(QSettings* settings, QObject* newParent = 0);
  118. ~ctkCommandLineParser();
  119. /**
  120. * Parse a given list of command line arguments.
  121. *
  122. * This method parses a list of QString elements considering the known arguments
  123. * added by calls to <code>addArgument()</code>. If any one of the argument
  124. * values does not match the corresponding regular expression,
  125. * <code>ok</code> is set to false and an empty QHash object is returned.
  126. *
  127. * The keys in the returned QHash object correspond to the long argument string,
  128. * if it is not empty. Otherwise, the short argument string is used as key. The
  129. * QVariant values can safely be converted to the type specified in the
  130. * <code>addArgument()</code> method call.
  131. *
  132. * @param arguments A QStringList containing command line arguments. Usually
  133. * given by <code>QCoreApplication::arguments()</code>.
  134. * @param ok A pointer to a boolean variable. Will be set to <code>true</code>
  135. * if all regular expressions matched, <code>false</code> otherwise.
  136. * @return A QHash object mapping the long argument (if empty, the short one)
  137. * to a QVariant containing the value.
  138. */
  139. QHash<QString, QVariant> parseArguments(const QStringList &arguments, bool* ok = 0);
  140. /**
  141. * Convenient method allowing to parse a given list of command line arguments.
  142. * @see parseArguments(const QStringList &, bool*)
  143. */
  144. QHash<QString, QVariant> parseArguments(int argc, char** argv, bool* ok = 0);
  145. /**
  146. * Returns a detailed error description if a call to <code>parseArguments()</code>
  147. * failed.
  148. *
  149. * @return The error description, empty if no error occured.
  150. * @see parseArguments(const QStringList&, bool*)
  151. */
  152. QString errorString() const;
  153. /**
  154. * This method returns all unparsed arguments, i.e. all arguments
  155. * for which no long or short name has been registered via a call
  156. * to <code>addArgument()</code>.
  157. *
  158. * @see addArgument()
  159. *
  160. * @return A list containing unparsed arguments.
  161. */
  162. const QStringList& unparsedArguments() const;
  163. /**
  164. * Checks if the given argument has been added via a call
  165. * to <code>addArgument()</code>.
  166. *
  167. * @see addArgument()
  168. *
  169. * @param argument The argument to be checked.
  170. * @return <code>true</code> if the argument was added, <code>false</code>
  171. * otherwise.
  172. */
  173. Q_INVOKABLE bool argumentAdded(const QString& argument) const;
  174. /**
  175. * Checks if the given argument has been parsed successfully by a previous
  176. * call to <code>parseArguments()</code>.
  177. *
  178. * @param argument The argument to be checked.
  179. * @return <code>true</code> if the argument was parsed, <code>false</code>
  180. * otherwise.
  181. */
  182. Q_INVOKABLE bool argumentParsed(const QString& argument) const;
  183. /**
  184. * Adds a command line argument. An argument can have a long name
  185. * (like --long-argument-name), a short name (like -l), or both. The type
  186. * of the argument can be specified by using the <code>type</code> parameter.
  187. * The following types are supported:
  188. *
  189. * <table>
  190. * <tr><td><b>Type</b></td><td><b># of parameters</b></td><td><b>Default regular expr</b></td>
  191. * <td><b>Example</b></td></tr>
  192. * <tr><td>QVariant::String</td><td>1</td><td>.*</td><td>--test-string StringParameter</td></tr>
  193. * <tr><td>QVariant::Bool</td><td>0</td><td>does not apply</td><td>--enable-something</td></tr>
  194. * <tr><td>QVariant::StringList</td><td>-1</td><td>.*</td><td>--test-list string1 string2</td></tr>
  195. * <tr><td>QVariant::Int</td><td>1</td><td>-?[0-9]+</td><td>--test-int -5</td></tr>
  196. * </table>
  197. *
  198. * The regular expressions are used to validate the parameters of command line
  199. * arguments. You can restrict the valid set of parameters by calling
  200. * <code>setExactMatchRegularExpression()</code> for your argument.
  201. *
  202. * Optionally, a help string and a default value can be provided for the argument. If
  203. * the QVariant type of the default value does not match <code>type</code>, an
  204. * exception is thrown. Arguments with default values are always returned by
  205. * <code>parseArguments()</code>.
  206. *
  207. * You can also declare an argument deprecated, by setting <code>deprecated</code>
  208. * to <code>true</code>. Alternatively you can add a deprecated argument by calling
  209. * <code>addDeprecatedArgument()</code>.
  210. *
  211. * If the long or short argument has already been added, or if both are empty strings,
  212. * the method call has no effect.
  213. *
  214. * @param longarg The long argument name.
  215. * @param shortarg The short argument name.
  216. * @param type The argument type (see the list above for supported types).
  217. * @param argHelp A help string describing the argument.
  218. * @param defaultValue A default value for the argument.
  219. * @param ignoreRest All arguments after the current one will be ignored.
  220. * @param deprecated Declares the argument deprecated.
  221. *
  222. * @see setExactMatchRegularExpression()
  223. * @see addDeprecatedArgument()
  224. * @throws std::logic_error If the QVariant type of <code>defaultValue</code>
  225. * does not match <code>type</code>, a <code>std::logic_error</code> is thrown.
  226. */
  227. void addArgument(const QString& longarg, const QString& shortarg,
  228. QVariant::Type type, const QString& argHelp = QString(),
  229. const QVariant& defaultValue = QVariant(),
  230. bool ignoreRest = false, bool deprecated = false);
  231. /**
  232. * Adds a deprecated command line argument. If a deprecated argument is provided
  233. * on the command line, <code>argHelp</code> is displayed in the console and
  234. * processing continues with the next argument.
  235. *
  236. * Deprecated arguments are grouped separately at the end of the help text
  237. * returned by <code>helpText()</code>.
  238. *
  239. * @param longarg The long argument name.
  240. * @param shortarg The short argument name.
  241. * @param argHelp A help string describing alternatives to the deprecated argument.
  242. */
  243. void addDeprecatedArgument(const QString& longarg, const QString& shortarg,
  244. const QString& argHelp);
  245. /**
  246. * Sets a custom regular expression for validating argument parameters. The method
  247. * <code>errorString()</code> can be used the get the last error description.
  248. *
  249. * @param argument The previously added long or short argument name.
  250. * @param expression A regular expression which the arugment parameters must match.
  251. * @param exactMatchFailedMessage An error message explaining why the parameter did
  252. * not match.
  253. *
  254. * @return <code>true</code> if the argument was found and the regular expression was set,
  255. * <code>false</code> otherwise.
  256. *
  257. * @see errorString()
  258. */
  259. bool setExactMatchRegularExpression(const QString& argument, const QString& expression,
  260. const QString& exactMatchFailedMessage);
  261. /**
  262. * The field width for the argument names without the help text.
  263. *
  264. * @return The argument names field width in the help text.
  265. */
  266. int fieldWidth() const;
  267. /**
  268. * Creates a help text containing properly formatted argument names and help strings
  269. * provided by calls to <code>addArgument()</code>. The arguments can be grouped by
  270. * using <code>beginGroup()</code> and <code>endGroup()</code>.
  271. *
  272. * @param charPad The padding character.
  273. * @return The formatted help text.
  274. */
  275. QString helpText(const char charPad = ' ') const;
  276. /**
  277. * Sets the argument prefix for long and short argument names. This can be used
  278. * to create native command line arguments without changing the calls to
  279. * <code>addArgument()</code>. For example on Unix-based systems, long argument
  280. * names start with "--" and short names with "-", while on Windows argument names
  281. * always start with "/".
  282. *
  283. * Note that all methods in ctkCommandLineParser which take an argument name
  284. * expect the name as it was supplied to <code>addArgument</code>.
  285. *
  286. * Example usage:
  287. *
  288. * \code
  289. * ctkCommandLineParser parser;
  290. * parser.setArgumentPrefix("--", "-");
  291. * parser.addArgument("long-argument", "l", QVariant::String);
  292. * QStringList args;
  293. * args << "program name" << "--long-argument Hi";
  294. * parser.parseArguments(args);
  295. * \endcode
  296. *
  297. * @param longPrefix The prefix for long argument names.
  298. * @param shortPrefix The prefix for short argument names.
  299. */
  300. void setArgumentPrefix(const QString& longPrefix, const QString& shortPrefix);
  301. /**
  302. * Begins a new group for documenting arguments. All newly added arguments via
  303. * <code>addArgument()</code> will be put in the new group. You can close the
  304. * current group by calling <code>endGroup()</code> or be opening a new group.
  305. *
  306. * Note that groups cannot be nested and all arguments which do not belong to
  307. * a group will be listed at the top of the text created by <code>helpText()</code>.
  308. *
  309. * @param description The description of the group
  310. */
  311. void beginGroup(const QString& description);
  312. /**
  313. * Ends the current group.
  314. *
  315. * @see beginGroup(const QString&)
  316. */
  317. void endGroup();
  318. /**
  319. * Enables QSettings support in ctkCommandLineParser. If an argument name is found
  320. * in the QSettings instance with a valid QVariant, the value is considered as
  321. * a default value and overwrites default values registered with
  322. * <code>addArgument()</code>. User supplied values on the command line overwrite
  323. * values in the QSettings instance, except for arguments with multiple parameters
  324. * which are merged with QSettings values. Call <code>mergeSettings(false)</code>
  325. * to disable merging.
  326. *
  327. * See <code>ctkCommandLineParser(QSettings*)</code> for information about how to
  328. * supply a QSettings instance.
  329. *
  330. * Additionally, a long and short argument name can be specified which will disable
  331. * QSettings support if supplied on the command line. The argument name must be
  332. * registered as a regular argument via <code>addArgument()</code>.
  333. *
  334. * @param disableLongArg Long argument name.
  335. * @param disableShortArg Short argument name.
  336. *
  337. * @see ctkCommandLineParser(QSettings*)
  338. */
  339. void enableSettings(const QString& disableLongArg = "",
  340. const QString& disableShortArg = "");
  341. /**
  342. * Controlls the merging behavior of user values and QSettings values.
  343. *
  344. * If merging is on (the default), user supplied values for an argument
  345. * which can take more than one parameter are merged with values stored
  346. * in the QSettings instance. If merging is off, the user values overwrite
  347. * the QSettings values.
  348. *
  349. * @param merge <code>true</code> enables QSettings merging, <code>false</code>
  350. * disables it.
  351. */
  352. void mergeSettings(bool merge);
  353. /**
  354. * Can be used to check if QSettings support has been enabled by a call to
  355. * <code>enableSettings()</code>.
  356. *
  357. * @return <code>true</code> if QSettings support is enabled, <code>false</code>
  358. * otherwise.
  359. */
  360. bool settingsEnabled() const;
  361. /**
  362. * Can be used to teach the parser to stop parsing the arguments and return False when
  363. * an unknown argument is encountered. By default <code>StrictMode</code> is disabled.
  364. *
  365. * @see parseArguments(const QStringList &, bool*)
  366. */
  367. void setStrictModeEnabled(bool strictMode);
  368. private:
  369. class ctkInternal;
  370. ctkInternal * Internal;
  371. };
  372. #endif