From f929a0f81b6f75f880796b3716ab8a858a764de9 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Tue, 5 Feb 2019 14:17:16 +0000 Subject: Recommit: Add support for prefix-only CLI options Summary: Add support for options that always prefix their value, giving an error if the value is in the next argument or if the option is given a value assignment (ie. opt=val). This is the desired behavior for the -D option of FileCheck for instance. Copyright: - Linaro (changes in version 2 of revision D55940) - GraphCore (changes in later versions and introduced when creating D56549) Reviewers: jdenny Subscribers: llvm-commits, probinson, kristina, hiraditya, JonChesterfield Differential Revision: https://reviews.llvm.org/D56549 llvm-svn: 353172 --- llvm/unittests/Support/CommandLineTest.cpp | 74 ++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'llvm/unittests/Support/CommandLineTest.cpp') diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index 150563b..f9841f5 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -1054,4 +1054,78 @@ TEST_F(GetOptionWidthTest, ExpectedStrSize); } +TEST(CommandLineTest, PrefixOptions) { + cl::ResetCommandLineParser(); + + StackOption> IncludeDirs( + "I", cl::Prefix, cl::desc("Declare an include directory")); + + // Test non-prefixed variant works with cl::Prefix options. + EXPECT_TRUE(IncludeDirs.empty()); + const char *args[] = {"prog", "-I=/usr/include"}; + EXPECT_TRUE( + cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls())); + EXPECT_TRUE(IncludeDirs.size() == 1); + EXPECT_TRUE(IncludeDirs.front().compare("/usr/include") == 0); + + IncludeDirs.erase(IncludeDirs.begin()); + cl::ResetAllOptionOccurrences(); + + // Test non-prefixed variant works with cl::Prefix options when value is + // passed in following argument. + EXPECT_TRUE(IncludeDirs.empty()); + const char *args2[] = {"prog", "-I", "/usr/include"}; + EXPECT_TRUE( + cl::ParseCommandLineOptions(3, args2, StringRef(), &llvm::nulls())); + EXPECT_TRUE(IncludeDirs.size() == 1); + EXPECT_TRUE(IncludeDirs.front().compare("/usr/include") == 0); + + IncludeDirs.erase(IncludeDirs.begin()); + cl::ResetAllOptionOccurrences(); + + // Test prefixed variant works with cl::Prefix options. + EXPECT_TRUE(IncludeDirs.empty()); + const char *args3[] = {"prog", "-I/usr/include"}; + EXPECT_TRUE( + cl::ParseCommandLineOptions(2, args3, StringRef(), &llvm::nulls())); + EXPECT_TRUE(IncludeDirs.size() == 1); + EXPECT_TRUE(IncludeDirs.front().compare("/usr/include") == 0); + + StackOption> MacroDefs( + "D", cl::AlwaysPrefix, cl::desc("Define a macro"), + cl::value_desc("MACRO[=VALUE]")); + + cl::ResetAllOptionOccurrences(); + + // Test non-prefixed variant does not work with cl::AlwaysPrefix options: + // equal sign is part of the value. + EXPECT_TRUE(MacroDefs.empty()); + const char *args4[] = {"prog", "-D=HAVE_FOO"}; + EXPECT_TRUE( + cl::ParseCommandLineOptions(2, args4, StringRef(), &llvm::nulls())); + EXPECT_TRUE(MacroDefs.size() == 1); + EXPECT_TRUE(MacroDefs.front().compare("=HAVE_FOO") == 0); + + MacroDefs.erase(MacroDefs.begin()); + cl::ResetAllOptionOccurrences(); + + // Test non-prefixed variant does not allow value to be passed in following + // argument with cl::AlwaysPrefix options. + EXPECT_TRUE(MacroDefs.empty()); + const char *args5[] = {"prog", "-D", "HAVE_FOO"}; + EXPECT_FALSE( + cl::ParseCommandLineOptions(3, args5, StringRef(), &llvm::nulls())); + EXPECT_TRUE(MacroDefs.empty()); + + cl::ResetAllOptionOccurrences(); + + // Test prefixed variant works with cl::AlwaysPrefix options. + EXPECT_TRUE(MacroDefs.empty()); + const char *args6[] = {"prog", "-DHAVE_FOO"}; + EXPECT_TRUE( + cl::ParseCommandLineOptions(2, args6, StringRef(), &llvm::nulls())); + EXPECT_TRUE(MacroDefs.size() == 1); + EXPECT_TRUE(MacroDefs.front().compare("HAVE_FOO") == 0); +} + } // anonymous namespace -- cgit v1.1