Skip to content

Commit 8366490

Browse files
authored
Merge pull request #243 from eseiler/fix/flag
[FIX] flags setting value to false
2 parents 31d3207 + 5c9e2f9 commit 8366490

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

include/sharg/detail/format_parse.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,9 @@ class format_parse : public format_base
715715
*/
716716
void get_flag(bool & value, char const short_id, std::string const & long_id)
717717
{
718-
value = flag_is_set(short_id) || flag_is_set(long_id);
718+
// `|| value` is needed to keep the value if it was set before.
719+
// It must be last because `flag_is_set` removes the flag from the arguments.
720+
value = flag_is_set(short_id) || flag_is_set(long_id) || value;
719721
}
720722

721723
/*!\brief Handles command line positional option retrieval.

test/unit/parser/format_parse_test.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,3 +881,79 @@ TEST_F(format_parse_test, executable_name)
881881
EXPECT_EQ(executable_name[0], "parser_test");
882882
EXPECT_EQ(executable_name[1], "build");
883883
}
884+
885+
TEST_F(format_parse_test, flag_independence)
886+
{
887+
bool flag_value{false};
888+
889+
auto parser = get_parser("-a", "-z");
890+
parser.add_flag(flag_value, sharg::config{.short_id = 'a'});
891+
parser.add_flag(flag_value, sharg::config{.short_id = 'z'});
892+
EXPECT_NO_THROW(parser.parse());
893+
EXPECT_EQ(flag_value, true);
894+
895+
flag_value = false;
896+
897+
parser = get_parser("-a");
898+
parser.add_flag(flag_value, sharg::config{.short_id = 'a'});
899+
parser.add_flag(flag_value, sharg::config{.short_id = 'z'});
900+
EXPECT_NO_THROW(parser.parse());
901+
EXPECT_EQ(flag_value, true);
902+
903+
flag_value = false;
904+
905+
parser = get_parser("-z");
906+
parser.add_flag(flag_value, sharg::config{.short_id = 'a'});
907+
parser.add_flag(flag_value, sharg::config{.short_id = 'z'});
908+
EXPECT_NO_THROW(parser.parse());
909+
EXPECT_EQ(flag_value, true);
910+
}
911+
912+
TEST_F(format_parse_test, parse_order_example)
913+
{
914+
bool flag_value{false};
915+
916+
// Flags are evaluated after options
917+
auto parser = get_parser("-f", "-o", "false");
918+
919+
EXPECT_NO_THROW(parser.add_option(flag_value, sharg::config{.short_id = 'o'}));
920+
EXPECT_NO_THROW(parser.add_flag(flag_value, sharg::config{.short_id = 'f'}));
921+
EXPECT_EQ(flag_value, false);
922+
EXPECT_NO_THROW(parser.parse());
923+
EXPECT_EQ(flag_value, true); // option sets to false, but flag sets to true
924+
925+
flag_value = false;
926+
927+
// Because this option syntax is also allowed
928+
parser = get_parser("-otrue");
929+
930+
EXPECT_NO_THROW(parser.add_option(flag_value, sharg::config{.short_id = 'o'}));
931+
EXPECT_EQ(flag_value, false);
932+
EXPECT_NO_THROW(parser.parse());
933+
EXPECT_EQ(flag_value, true);
934+
935+
flag_value = false;
936+
937+
// And this flag syntax is allowed
938+
parser = get_parser("-otrue");
939+
std::array<bool, 5> flag_values{false, false, false, false, false};
940+
941+
EXPECT_NO_THROW(parser.add_flag(flag_values[0], sharg::config{.short_id = 'o'}));
942+
EXPECT_NO_THROW(parser.add_flag(flag_values[1], sharg::config{.short_id = 't'}));
943+
EXPECT_NO_THROW(parser.add_flag(flag_values[2], sharg::config{.short_id = 'r'}));
944+
EXPECT_NO_THROW(parser.add_flag(flag_values[3], sharg::config{.short_id = 'u'}));
945+
EXPECT_NO_THROW(parser.add_flag(flag_values[4], sharg::config{.short_id = 'e'}));
946+
EXPECT_TRUE(std::ranges::none_of(flag_values, std::identity{})); // All false
947+
EXPECT_NO_THROW(parser.parse());
948+
EXPECT_TRUE(std::ranges::all_of(flag_values, std::identity{})); // All true
949+
950+
// Positional options are evaluated last
951+
parser = get_parser("false", "-o", "true", "-f");
952+
953+
EXPECT_NO_THROW(parser.add_option(flag_value, sharg::config{.short_id = 'o'}));
954+
EXPECT_NO_THROW(parser.add_flag(flag_value, sharg::config{.short_id = 'f'}));
955+
EXPECT_NO_THROW(parser.add_positional_option(flag_value, sharg::config{}));
956+
EXPECT_EQ(flag_value, false);
957+
EXPECT_NO_THROW(parser.parse());
958+
EXPECT_EQ(flag_value, false);
959+
}

0 commit comments

Comments
 (0)