From bc5e6ee87a08618c3202eb1cecddd24267e64701 Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Mon, 14 Jan 2019 09:28:53 +0000 Subject: 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: 351038 --- llvm/unittests/Support/CommandLineTest.cpp | 76 +++++++++++++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-) (limited to 'llvm/unittests/Support') diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index a296912a305..9d06f7265a7 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -840,4 +840,78 @@ TEST(CommandLineTest, GetCommandLineArguments) { } #endif -} // anonymous namespace +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.2.3