state->namespace_start = options;
const Option *opt;
+
+ /* Verify that the option array didn't get mangled within a namespace. */
+ for (opt = options; opt < options_end; opt++)
+ if (opt + 1 < options_end && !FLAGS_SET((opt + 1)->flags, OPTION_NAMESPACE_MARKER))
+ assert_se(opt->id < (opt + 1)->id);
+
for (opt = options; opt < options_end; opt++) {
bool ns_marker = FLAGS_SET(opt->flags, OPTION_NAMESPACE_MARKER);
if (!in_ns) {
* and in a single (unnamed) group. OPTION_NAMESPACE() marks the beginning of a named namespace.
* OPTION_GROUP() marks the beginning of a named group.
*
- * Note: if multiple namespaces are used, they should all be named.
+ * Note: if multiple namespaces are used, they should all be named, i.e. each separate parse_argv
+ * instance should have OPTION_NAMESPACE first, and then its set of OPTION()s. (This is because
+ * clang reorders OPTIONs coming from different functions. So an unnamed group could end up being
+ * merged with one of the earlier groups. It seems that reordering within a single function does
+ * not happen.)
+ *
+ * When groups are used, the first group may be named (with OPTION_GROUP appearing before any
+ * options), or it may be unnamed. Both variants should work fine.
*/
typedef enum OptionFlags {
TEST(option_group_marker) {
static const Option options[] = {
- { 1, .short_code = 'h', .long_code = "help" },
- { 2, .long_code = "version" },
- { 0, .long_code = "AdvancedGroup", .flags = OPTION_GROUP_MARKER },
- { 3, .long_code = "debug" },
- { 4, .long_code = "Advance" }, /* prefix match with the group */
- { 5, .long_code = "defilbrilate" },
+ { __COUNTER__, .short_code = 'h', .long_code = "help" },
+ { __COUNTER__, .long_code = "version" },
+ { __COUNTER__, .long_code = "AdvancedGroup", .flags = OPTION_GROUP_MARKER },
+ { __COUNTER__, .long_code = "debug" },
+ { __COUNTER__, .long_code = "Advance" }, /* prefix match with the group */
+ { __COUNTER__, .long_code = "defilbrilate" },
{}
};
* peeks at the next arg to handle legacy "space-separated" form. */
TEST(option_optional_arg_consume) {
static const Option options[] = {
- { 1, .short_code = 'h', .long_code = "help" },
- { 2, .long_code = "user", .metavar = "NAME", .flags = OPTION_OPTIONAL_ARG },
- { 3, .short_code = 'u', .long_code = "uid", .metavar = "USER" },
+ { __COUNTER__, .short_code = 'h', .long_code = "help" },
+ { __COUNTER__, .long_code = "user", .metavar = "NAME", .flags = OPTION_OPTIONAL_ARG },
+ { __COUNTER__, .short_code = 'u', .long_code = "uid", .metavar = "USER" },
{}
};