diff --git a/include/ArgParser/ArgParser.hpp b/include/ArgParser/ArgParser.hpp index f58bb19..b4cffd6 100644 --- a/include/ArgParser/ArgParser.hpp +++ b/include/ArgParser/ArgParser.hpp @@ -88,6 +88,8 @@ class ArgParser { const ArgPtr& GetArgument(const std::string& full_name) const; bool ParseArgument(ParseContext&); + bool ParseTypeArgument(ParseContext&, bool = false); + bool ParseMultivalue(ParseContext&); bool ParseStringArgument(ParseContext&); bool ParseIntArgument(ParseContext&); bool ParseFlagArgument(ParseContext&); diff --git a/src/ArgParser/ArgParser.cpp b/src/ArgParser/ArgParser.cpp index c8e3482..4c4abb4 100644 --- a/src/ArgParser/ArgParser.cpp +++ b/src/ArgParser/ArgParser.cpp @@ -196,31 +196,53 @@ auto ArgParser::ValidateShortArgument(const std::string& arg) } bool ArgParser::NextValueExists(ParseContext& ctx) const { - if (!ctx.is_named && ctx.index + 1 >= ctx.args.size()) { - std::cerr << "Expected value for argument: " << ctx.full_name << std::endl; - return false; - } - return true; + return ctx.is_named || ctx.index + 1 < ctx.args.size(); } -bool ArgParser::ParseArgument(ParseContext& context) { +bool ArgParser::ParseTypeArgument(ParseContext& context, bool has_parsed) { switch (GetArgument(context.full_name)->GetType()) { case ArgumentType::kString: { - return ParseStringArgument(context); + if (!ParseStringArgument(context) && !has_parsed) + return false; + break; } case ArgumentType::kInt: { - return ParseIntArgument(context); + if (!ParseIntArgument(context) && !has_parsed) + return false; + break; } case ArgumentType::kFlag: { - return ParseFlagArgument(context); + if (!ParseFlagArgument(context) && !has_parsed) + return false; + break; } } return true; } +bool ArgParser::ParseMultivalue(ParseContext& context) { + bool has_parsed = false; + while (NextValueExists(context) && (!context.args[context.index + 1].starts_with("-") || !has_parsed)) { + std::cout << "ind = " << context.index << '\n'; + if (!ParseTypeArgument(context, has_parsed)) + return false; + has_parsed = true; + } + return true; +} + +bool ArgParser::ParseArgument(ParseContext& context) { + if (context.is_named || !GetArgument(context.full_name)->IsMultiValue()) + return ParseTypeArgument(context); + return ParseMultivalue(context); +} + bool ArgParser::ParseStringArgument(ParseContext& ctx) { - if (!NextValueExists(ctx)) + if (!NextValueExists(ctx)) { + std::cerr << "Expected value for argument: " << ctx.full_name << std::endl; return false; + } + std::cout << ctx.index << ") " << ctx.args[ctx.index] << "\n"; ArgPtr& argument = GetArgument(ctx.full_name); std::string value; @@ -235,8 +257,11 @@ bool ArgParser::ParseStringArgument(ParseContext& ctx) { bool ArgParser::ParseIntArgument(ParseContext& ctx) { ArgPtr& argument = GetArgument(ctx.full_name); - if (!NextValueExists(ctx)) + if (!NextValueExists(ctx)) { + std::cerr << "Expected value for argument: " << ctx.full_name << std::endl; return false; + } + int64_t number; const char* value_str = ctx.is_named ? ctx.args[ctx.index].c_str() + ctx.equal_pos + 1 diff --git a/tests/argparser_test.cpp b/tests/argparser_test.cpp index efb7b98..7f9a1ff 100644 --- a/tests/argparser_test.cpp +++ b/tests/argparser_test.cpp @@ -191,3 +191,21 @@ TEST(ArgParserTestSuite, HelpTest) { ASSERT_TRUE(parser.Parse(SplitString("app --help"))); ASSERT_TRUE(parser.Help()); } + +TEST(ArgParserTestSuite, Multivalue) { + ArgParser parser("My Parser"); + parser.AddStringArgument("inputs").MultiValue(); + parser.AddStringArgument("outputs").MultiValue(); + ASSERT_TRUE(parser.Parse(SplitString("app --inputs input1.txt input2.txt --outputs output1.txt output2.txt"))); + ASSERT_EQ(parser.GetStringValue("inputs", 0), "input1.txt"); + ASSERT_EQ(parser.GetStringValue("inputs", 1), "input2.txt"); + ASSERT_EQ(parser.GetStringValue("outputs", 0), "output1.txt"); + ASSERT_EQ(parser.GetStringValue("outputs", 1), "output2.txt"); +} + +TEST(ArgParseTestSuite, MinArgs) { + ArgParser parser("My Parser"); + parser.AddIntArgument('n', "numbers").MultiValue(3); + parser.AddStringArgument('s', "strings").MultiValue(1); + ASSERT_TRUE(parser.Parse(SplitString("app -n 1 2 3 -s hello"))); +}