{"id":12816,"url":"https://patchwork.libcamera.org/api/patches/12816/?format=json","web_url":"https://patchwork.libcamera.org/patch/12816/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20210707021941.20804-4-laurent.pinchart@ideasonboard.com>","date":"2021-07-07T02:19:14","name":"[libcamera-devel,03/30] cam: options: Document the options parser API","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"e00edb1dd82236f8eab470b3d90838dd707eada3","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/?format=json","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/12816/mbox/","series":[{"id":2213,"url":"https://patchwork.libcamera.org/api/series/2213/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=2213","date":"2021-07-07T02:19:12","name":"Multi-camera support in the cam application","version":1,"mbox":"https://patchwork.libcamera.org/series/2213/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/12816/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/12816/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 0FE6BBD794\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed,  7 Jul 2021 02:20:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id AB30768516;\n\tWed,  7 Jul 2021 04:20:36 +0200 (CEST)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id ADC5668502\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  7 Jul 2021 04:20:32 +0200 (CEST)","from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 2E4F9DEF\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed,  7 Jul 2021 04:20:32 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"aTQu08I/\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1625624432;\n\tbh=nW8FIUz/LlqWAxKMSXMbQy2iNp4Y62/GLykP65KiCn8=;\n\th=From:To:Subject:Date:In-Reply-To:References:From;\n\tb=aTQu08I/+XyLjIKuv1Vk/0n6nSpcMVCxOecWBBfUrw4BxjRHzIAHcO7+sPd8RDONd\n\tF4+3L+bmGgLSvnR1TS5ZnkTRSGDQD795t/Qgzfen/zhsDlJbRrZYPk8IJLZsbp4cxK\n\tBs7OW533+KLoeyV6DmV0UK7a+FVfh8QsNjNJMdeg=","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"libcamera-devel@lists.libcamera.org","Date":"Wed,  7 Jul 2021 05:19:14 +0300","Message-Id":"<20210707021941.20804-4-laurent.pinchart@ideasonboard.com>","X-Mailer":"git-send-email 2.31.1","In-Reply-To":"<20210707021941.20804-1-laurent.pinchart@ideasonboard.com>","References":"<20210707021941.20804-1-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","Subject":"[libcamera-devel] [PATCH 03/30] cam: options: Document the options\n\tparser API","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"Before extending the option parser, document its existing API.\n\nSigned-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n---\n src/cam/options.cpp | 399 ++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 399 insertions(+)","diff":"diff --git a/src/cam/options.cpp b/src/cam/options.cpp\nindex 41968caa0ccb..da218c4644d3 100644\n--- a/src/cam/options.cpp\n+++ b/src/cam/options.cpp\n@@ -13,10 +13,80 @@\n \n #include \"options.h\"\n \n+/**\n+ * \\enum OptionArgument\n+ * \\brief Indicate if an option takes an argument\n+ *\n+ * \\var OptionArgument::ArgumentNone\n+ * \\brief The option doesn't accept any argument\n+ *\n+ * \\var OptionArgument::ArgumentRequired\n+ * \\brief The option requires an argument\n+ *\n+ * \\var OptionArgument::ArgumentOptional\n+ * \\brief The option accepts an optional argument\n+ */\n+\n+/**\n+ * \\enum OptionType\n+ * \\brief The type of argument for an option\n+ *\n+ * \\var OptionType::OptionNone\n+ * \\brief No argument type, used for options that take no argument\n+ *\n+ * \\var OptionType::OptionInteger\n+ * \\brief Integer argument type, with an optional base prefix (`0` for base 8,\n+ * `0x` for base 16, none for base 10)\n+ *\n+ * \\var OptionType::OptionString\n+ * \\brief String argument\n+ *\n+ * \\var OptionType::OptionKeyValue\n+ * \\brief key=value list argument\n+ */\n+\n /* -----------------------------------------------------------------------------\n  * Option\n  */\n \n+/**\n+ * \\struct Option\n+ * \\brief Store metadata about an option\n+ *\n+ * \\var Option::opt\n+ * \\brief The option identifier\n+ *\n+ * \\var Option::type\n+ * \\brief The type of the option argument\n+ *\n+ * \\var Option::name\n+ * \\brief The option name\n+ *\n+ * \\var Option::argument\n+ * \\brief Whether the option accepts an optional argument, a mandatory\n+ * argument, or no argument at all\n+ *\n+ * \\var Option::argumentName\n+ * \\brief The argument name used in the help text\n+ *\n+ * \\var Option::help\n+ * \\brief The help text (may be a multi-line string)\n+ *\n+ * \\var Option::keyValueParser\n+ * \\brief For options of type OptionType::OptionKeyValue, the key-value parser\n+ * to parse the argument\n+ *\n+ * \\var Option::isArray\n+ * \\brief Whether the option can appear once or multiple times\n+ *\n+ * \\fn Option::hasShortOption()\n+ * \\brief Tell if the option has a short option specifier (e.g. `-f`)\n+ * \\return True if the option has a short option specifier, false otherwise\n+ *\n+ * \\fn Option::hasLongOption()\n+ * \\brief Tell if the option has a long option specifier (e.g. `--foo`)\n+ * \\return True if the option has a long option specifier, false otherwise\n+ */\n struct Option {\n \tint opt;\n \tOptionType type;\n@@ -32,6 +102,10 @@ struct Option {\n \tconst char *typeName() const;\n };\n \n+/**\n+ * \\brief Retrieve a string describing the option type\n+ * \\return A string describing the option type\n+ */\n const char *Option::typeName() const\n {\n \tswitch (type) {\n@@ -55,24 +129,65 @@ const char *Option::typeName() const\n  * OptionBase<T>\n  */\n \n+/**\n+ * \\class template<typename T> OptionBase\n+ * \\brief Container to store the values of parsed options\n+ * \\tparam T The type through which options are identified\n+ *\n+ *\n+ * The OptionsBase class is generated by a parser (either OptionsParser or\n+ * KeyValueParser) when parsing options. It stores values for all the options\n+ * found, and exposes accessor functions to retrieve them. The options are\n+ * accessed through an identifier to type \\a T, which is an int referencing an\n+ * Option::opt for OptionsParser, or a std::string referencing an Option::name\n+ * for KeyValueParser.\n+ */\n+\n+/**\n+ * \\fn OptionsBase::OptionsBase()\n+ * \\brief Construct an OptionsBase instance\n+ *\n+ * The constructed instance is initially invalid, and will be populated by the\n+ * options parser.\n+ */\n+\n+/**\n+ * \\brief Tell if the stored options list is empty\n+ * \\return True if the container is empty, false otherwise\n+ */\n template<typename T>\n bool OptionsBase<T>::empty() const\n {\n \treturn values_.empty();\n }\n \n+/**\n+ * \\brief Tell if the options parsing completed successfully\n+ * \\return True if the container is returned after successfully parsing\n+ * options, false if it is returned after an error was detected during parsing\n+ */\n template<typename T>\n bool OptionsBase<T>::valid() const\n {\n \treturn valid_;\n }\n \n+/**\n+ * \\brief Tell if the option \\a opt is specified\n+ * \\param[in] opt The option to search for\n+ * \\return True if the \\a opt option is set, false otherwise\n+ */\n template<typename T>\n bool OptionsBase<T>::isSet(const T &opt) const\n {\n \treturn values_.find(opt) != values_.end();\n }\n \n+/**\n+ * \\brief Retrieve the value of option \\a opt\n+ * \\param[in] opt The option to retrieve\n+ * \\return The value of option \\a opt if found, an empty OptionValue otherwise\n+ */\n template<typename T>\n const OptionValue &OptionsBase<T>::operator[](const T &opt) const\n {\n@@ -84,6 +199,13 @@ const OptionValue &OptionsBase<T>::operator[](const T &opt) const\n \treturn empty;\n }\n \n+/**\n+ * \\brief Mark the container as invalid\n+ *\n+ * This function can be used in a key-value parser's override of the\n+ * KeyValueParser::parse() function to mark the returned options as invalid if\n+ * a validation error occurs.\n+ */\n template<typename T>\n void OptionsBase<T>::invalidate()\n {\n@@ -144,9 +266,46 @@ template class OptionsBase<std::string>;\n  * KeyValueParser\n  */\n \n+/**\n+ * \\class KeyValueParser\n+ * \\brief A specialized parser for list of key-value pairs\n+ *\n+ * The KeyValueParser is an options parser for comma-separated lists of\n+ * `key=value` pairs. The supported keys are added to the parser with\n+ * addOption(). A given key can only appear once in the parsed list.\n+ *\n+ * Instances of this class can be passed to the OptionsParser::addOption()\n+ * function to create options that take key-value pairs as an option argument.\n+ * Specialized versions of the key-value parser can be created by inheriting\n+ * from this class, to pre-build the options list in the constructor, and to add\n+ * custom validation by overriding the parse() function.\n+ */\n+\n+/**\n+ * \\class KeyValueParser::Options\n+ * \\brief An options list generated by the key-value parser\n+ *\n+ * This is a specialization of OptionsBase with the option reference type set to\n+ * std::string.\n+ */\n+\n KeyValueParser::KeyValueParser() = default;\n KeyValueParser::~KeyValueParser() = default;\n \n+/**\n+ * \\brief Add a supported option to the parser\n+ * \\param[in] name The option name, corresponding to the key name in the\n+ * key=value pair. The name shall be unique.\n+ * \\param[in] type The type of the value in the key=value pair\n+ * \\param[in] help The help text\n+ * \\param[in] argument Whether the value is optional, mandatory or not allowed.\n+ * Shall be ArgumentNone if \\a type is OptionNone.\n+ *\n+ * \\sa OptionsParser\n+ *\n+ * \\return True if the option was added successfully, false if an error\n+ * occurred.\n+ */\n bool KeyValueParser::addOption(const char *name, OptionType type,\n \t\t\t       const char *help, OptionArgument argument)\n {\n@@ -166,6 +325,17 @@ bool KeyValueParser::addOption(const char *name, OptionType type,\n \treturn true;\n }\n \n+/**\n+ * \\brief Parse a string containing a list of key-value pairs\n+ * \\param[in] arguments The key-value pairs string to parse\n+ *\n+ * If a parsing error occurs, the parsing stops and the function returns an\n+ * invalid container. The container is populated with the options successfully\n+ * parsed so far.\n+ *\n+ * \\return A valid container with the list of parsed options on success, or an\n+ * invalid container otherwise\n+ */\n KeyValueParser::Options KeyValueParser::parse(const char *arguments)\n {\n \tOptions options;\n@@ -278,31 +448,98 @@ void KeyValueParser::usage(int indent)\n  * OptionValue\n  */\n \n+/**\n+ * \\class OptionValue\n+ * \\brief Container to store the value of an option\n+ *\n+ * The OptionValue class is a variant-type container to store the value of an\n+ * option. It supports empty values, integers, strings, key-value lists, as well\n+ * as arrays of those types. For array values, all array elements shall have the\n+ * same type.\n+ */\n+\n+/**\n+ * \\enum OptionValue::ValueType\n+ * \\brief The option value type\n+ *\n+ * \\var OptionValue::ValueType::ValueNone\n+ * \\brief Empty value\n+ *\n+ * \\var OptionValue::ValueType::ValueInteger\n+ * \\brief Integer value (int)\n+ *\n+ * \\var OptionValue::ValueType::ValueString\n+ * \\brief String value (std::string)\n+ *\n+ * \\var OptionValue::ValueType::ValueKeyValue\n+ * \\brief Key-value list value (KeyValueParser::Options)\n+ *\n+ * \\var OptionValue::ValueType::ValueArray\n+ * \\brief Array value\n+ */\n+\n+/**\n+ * \\brief Construct an empty OptionValue instance\n+ *\n+ * The value type is set to ValueType::ValueNone.\n+ */\n OptionValue::OptionValue()\n \t: type_(ValueNone), integer_(0)\n {\n }\n \n+/**\n+ * \\brief Construct an integer OptionValue instance\n+ * \\param[in] value The integer value\n+ *\n+ * The value type is set to ValueType::ValueInteger.\n+ */\n OptionValue::OptionValue(int value)\n \t: type_(ValueInteger), integer_(value)\n {\n }\n \n+/**\n+ * \\brief Construct a string OptionValue instance\n+ * \\param[in] value The string value\n+ *\n+ * The value type is set to ValueType::ValueString.\n+ */\n OptionValue::OptionValue(const char *value)\n \t: type_(ValueString), integer_(0), string_(value)\n {\n }\n \n+/**\n+ * \\brief Construct a string OptionValue instance\n+ * \\param[in] value The string value\n+ *\n+ * The value type is set to ValueType::ValueString.\n+ */\n OptionValue::OptionValue(const std::string &value)\n \t: type_(ValueString), integer_(0), string_(value)\n {\n }\n \n+/**\n+ * \\brief Construct a key-value OptionValue instance\n+ * \\param[in] value The key-value list\n+ *\n+ * The value type is set to ValueType::ValueKeyValue.\n+ */\n OptionValue::OptionValue(const KeyValueParser::Options &value)\n \t: type_(ValueKeyValue), integer_(0), keyValues_(value)\n {\n }\n \n+/**\n+ * \\brief Add an entry to an array value\n+ * \\param[in] value The entry value\n+ *\n+ * This function can only be called if the OptionValue type is\n+ * ValueType::ValueNone or ValueType::ValueArray. Upon return, the type will be\n+ * set to ValueType::ValueArray.\n+ */\n void OptionValue::addValue(const OptionValue &value)\n {\n \tassert(type_ == ValueNone || type_ == ValueArray);\n@@ -311,26 +548,57 @@ void OptionValue::addValue(const OptionValue &value)\n \tarray_.push_back(value);\n }\n \n+/**\n+ * \\fn OptionValue::type()\n+ * \\brief Retrieve the value type\n+ * \\return The value type\n+ */\n+\n+/**\n+ * \\brief Cast the value to an int\n+ * \\return The option value as an int, or 0 if the value type isn't\n+ * ValueType::ValueInteger\n+ */\n OptionValue::operator int() const\n {\n \treturn toInteger();\n }\n \n+/**\n+ * \\brief Cast the value to a std::string\n+ * \\return The option value as an std::string, or an empty string if the value\n+ * type isn't ValueType::ValueString\n+ */\n OptionValue::operator std::string() const\n {\n \treturn toString();\n }\n \n+/**\n+ * \\brief Cast the value to a key-value list\n+ * \\return The option value as a KeyValueParser::Options, or an empty list if\n+ * the value type isn't ValueType::ValueKeyValue\n+ */\n OptionValue::operator KeyValueParser::Options() const\n {\n \treturn toKeyValues();\n }\n \n+/**\n+ * \\brief Cast the value to an array\n+ * \\return The option value as a std::vector of OptionValue, or an empty vector\n+ * if the value type isn't ValueType::ValueArray\n+ */\n OptionValue::operator std::vector<OptionValue>() const\n {\n \treturn toArray();\n }\n \n+/**\n+ * \\brief Retrieve the value as an int\n+ * \\return The option value as an int, or 0 if the value type isn't\n+ * ValueType::ValueInteger\n+ */\n int OptionValue::toInteger() const\n {\n \tif (type_ != ValueInteger)\n@@ -339,6 +607,11 @@ int OptionValue::toInteger() const\n \treturn integer_;\n }\n \n+/**\n+ * \\brief Retrieve the value as a std::string\n+ * \\return The option value as a std::string, or an empty string if the value\n+ * type isn't ValueType::ValueString\n+ */\n std::string OptionValue::toString() const\n {\n \tif (type_ != ValueString)\n@@ -347,6 +620,11 @@ std::string OptionValue::toString() const\n \treturn string_;\n }\n \n+/**\n+ * \\brief Retrieve the value as a key-value list\n+ * \\return The option value as a KeyValueParser::Options, or an empty list if\n+ * the value type isn't ValueType::ValueKeyValue\n+ */\n KeyValueParser::Options OptionValue::toKeyValues() const\n {\n \tif (type_ != ValueKeyValue)\n@@ -355,6 +633,11 @@ KeyValueParser::Options OptionValue::toKeyValues() const\n \treturn keyValues_;\n }\n \n+/**\n+ * \\brief Retrieve the value as an array\n+ * \\return The option value as a std::vector of OptionValue, or an empty vector\n+ * if the value type isn't ValueType::ValueArray\n+ */\n std::vector<OptionValue> OptionValue::toArray() const\n {\n \tif (type_ != ValueArray)\n@@ -367,9 +650,91 @@ std::vector<OptionValue> OptionValue::toArray() const\n  * OptionsParser\n  */\n \n+/**\n+ * \\class OptionsParser\n+ * \\brief A command line options parser\n+ *\n+ * The OptionsParser class is an easy to use options parser for POSIX-style\n+ * command line options. Supports short (e.g. `-f`) and long (e.g. `--foo`)\n+ * options, optional and mandatory arguments, automatic parsing arguments for\n+ * integer types and comma-separated list of key=value pairs, and multi-value\n+ * arguments. It handles help text generation automatically.\n+ *\n+ * An OptionsParser instance is initialized by adding supported options with\n+ * addOption(). Options are specified by an identifier and a name. If the\n+ * identifier is an alphanumeric character, it will be used by the parser as a\n+ * short option identifier (e.g. `-f`). The name, if specified, will be used as\n+ * a long option identifier (e.g. `--foo`). It should not include the double\n+ * dashes. The name is optional if the option identifier is an alphanumeric\n+ * character and mandatory otherwise.\n+ *\n+ * An options has a mandatory help text, which is used to print the full options\n+ * list with the usage() function. The help text may be a multi-line string.\n+ * Correct indentation of the help text is handled automatically.\n+ *\n+ * Options accept arguments when created with OptionArgument::ArgumentRequired\n+ * or OptionArgument::ArgumentOptional. If the argument is required, it can be\n+ * specified as a positional argument after the option (e.g. `-f bar`,\n+ * `--foo bar`), collated with the short option (e.g. `-fbar`) or separated from\n+ * the long option by an equal sign (e.g. `--foo=bar`'). When the argument is\n+ * optional, it must be collated with the short option or separated from the\n+ * long option by an equal sign.\n+ *\n+ * If an option has a required or optional argument, an argument name must be\n+ * set when adding the option. The argument name is used in the help text as a\n+ * place holder for an argument value. For instance, a `--write` option that\n+ * takes a file name as an argument could set the argument name to `filename`,\n+ * and the help text would display `--write filename`. This is only used to\n+ * clarify the help text and has no effect on option parsing.\n+ *\n+ * The option type tells the parser how to process the argument. Arguments for\n+ * string options (OptionType::OptionString) are stored as-is without any\n+ * processing. Arguments for integer options (OptionType::OptionInteger) are\n+ * converted to an integer value, using an optional base prefix (`0` for base 8,\n+ * `0x` for base 16, none for base 10). Arguments for key-value options are\n+ * parsed by a KeyValueParser given to addOption().\n+ *\n+ * By default, a given option can appear once only in the parsed command line.\n+ * If the option is created as an array option, the parser will accept multiple\n+ * instances of the option. The order in which identical options are specified\n+ * is preserved in the values of an array option.\n+ *\n+ * After preparing the parser, it can be used any number of times to parse\n+ * command line options with the parse() function. The function returns an\n+ * Options instance that stores the values for the parsed options. The\n+ * Options::isSet() function can be used to test if an option has been found,\n+ * and is the only way to access options that take no argument (specified by\n+ * OptionType::OptionNone and OptionArgument::ArgumentNone). For options that\n+ * accept an argument, the option value can be access by Options::operator[]()\n+ * using the option identifier as the key. The order in which different options\n+ * are specified on the command line isn't preserved.\n+ */\n+\n+/**\n+ * \\class OptionsParser::Options\n+ * \\brief An options list generated by the options parser\n+ *\n+ * This is a specialization of OptionsBase with the option reference type set to\n+ * int.\n+ */\n+\n OptionsParser::OptionsParser() = default;\n OptionsParser::~OptionsParser() = default;\n \n+/**\n+ * \\brief Add an option to the parser\n+ * \\param[in] opt The option identifier\n+ * \\param[in] type The type of the option argument\n+ * \\param[in] help The help text (may be a multi-line string)\n+ * \\param[in] name The option name\n+ * \\param[in] argument Whether the option accepts an optional argument, a\n+ * mandatory argument, or no argument at all\n+ * \\param[in] argumentName The argument name used in the help text\n+ * \\param[in] array Whether the option can appear once or multiple times\n+ *\n+ * \\return True if the option was added successfully, false if an error\n+ * occurred.\n+ */\n bool OptionsParser::addOption(int opt, OptionType type, const char *help,\n \t\t\t      const char *name, OptionArgument argument,\n \t\t\t      const char *argumentName, bool array)\n@@ -395,6 +760,19 @@ bool OptionsParser::addOption(int opt, OptionType type, const char *help,\n \treturn true;\n }\n \n+/**\n+ * \\brief Add a key-value pair option to the parser\n+ * \\param[in] opt The option identifier\n+ * \\param[in] parser The KeyValueParser for the option value\n+ * \\param[in] help The help text (may be a multi-line string)\n+ * \\param[in] name The option name\n+ * \\param[in] array Whether the option can appear once or multiple times\n+ *\n+ * \\sa Option\n+ *\n+ * \\return True if the option was added successfully, false if an error\n+ * occurred.\n+ */\n bool OptionsParser::addOption(int opt, KeyValueParser *parser, const char *help,\n \t\t\t      const char *name, bool array)\n {\n@@ -406,6 +784,19 @@ bool OptionsParser::addOption(int opt, KeyValueParser *parser, const char *help,\n \treturn true;\n }\n \n+/**\n+ * \\brief Parse command line arguments\n+ * \\param[in] argc The number of arguments in the \\a argv array\n+ * \\param[in] argv The array of arguments\n+ *\n+ * If a parsing error occurs, the parsing stops, the function prints an error\n+ * message that identifies the invalid argument, prints usage information with\n+ * usage(), and returns an invalid container. The container is populated with\n+ * the options successfully parsed so far.\n+ *\n+ * \\return A valid container with the list of parsed options on success, or an\n+ * invalid container otherwise\n+ */\n OptionsParser::Options OptionsParser::parse(int argc, char **argv)\n {\n \tOptionsParser::Options options;\n@@ -485,6 +876,14 @@ OptionsParser::Options OptionsParser::parse(int argc, char **argv)\n \treturn options;\n }\n \n+/**\n+ * \\brief Print usage text to std::cerr\n+ *\n+ * The usage text list all the supported option with their arguments. It is\n+ * generated automatically from the options added to the parser. Caller of this\n+ * function may print additional usage information for the application before\n+ * the list of options.\n+ */\n void OptionsParser::usage()\n {\n \tstd::cerr << \"Options:\" << std::endl;\n","prefixes":["libcamera-devel","03/30"]}