diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-01-02 19:17:04 +0000 |
commit | b915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch) | |
tree | 98b8f811c7aff2547cab8642daf372d6c59502fb /unittests/Support/CommandLineTest.cpp | |
parent | 6421cca32f69ac849537a3cff78c352195e99f1b (diff) |
Notes
Diffstat (limited to 'unittests/Support/CommandLineTest.cpp')
-rw-r--r-- | unittests/Support/CommandLineTest.cpp | 142 |
1 files changed, 118 insertions, 24 deletions
diff --git a/unittests/Support/CommandLineTest.cpp b/unittests/Support/CommandLineTest.cpp index 9b24c1e40bca..945eb1d4e1cf 100644 --- a/unittests/Support/CommandLineTest.cpp +++ b/unittests/Support/CommandLineTest.cpp @@ -7,11 +7,15 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Config/config.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" #include "llvm/Support/StringSaver.h" #include "gtest/gtest.h" +#include <fstream> #include <stdlib.h> #include <string> @@ -76,8 +80,8 @@ public: class StackSubCommand : public cl::SubCommand { public: - StackSubCommand(const char *const Name, - const char *const Description = nullptr) + StackSubCommand(StringRef Name, + StringRef Description = StringRef()) : SubCommand(Name, Description) {} StackSubCommand() : SubCommand() {} @@ -168,7 +172,7 @@ typedef void ParserFunction(StringRef Source, StringSaver &Saver, SmallVectorImpl<const char *> &NewArgv, bool MarkEOLs); -void testCommandLineTokenizer(ParserFunction *parse, const char *Input, +void testCommandLineTokenizer(ParserFunction *parse, StringRef Input, const char *const Output[], size_t OutputSize) { SmallVector<const char *, 0> Actual; BumpPtrAllocator A; @@ -182,7 +186,7 @@ void testCommandLineTokenizer(ParserFunction *parse, const char *Input, } TEST(CommandLineTest, TokenizeGNUCommandLine) { - const char *Input = + const char Input[] = "foo\\ bar \"foo bar\" \'foo bar\' 'foo\\\\bar' -DFOO=bar\\(\\) " "foo\"bar\"baz C:\\\\src\\\\foo.cpp \"C:\\src\\foo.cpp\""; const char *const Output[] = { @@ -193,7 +197,7 @@ TEST(CommandLineTest, TokenizeGNUCommandLine) { } TEST(CommandLineTest, TokenizeWindowsCommandLine) { - const char *Input = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr " + const char Input[] = "a\\b c\\\\d e\\\\\"f g\" h\\\"i j\\\\\\\"k \"lmn\" o pqr " "\"st \\\"u\" \\v"; const char *const Output[] = { "a\\b", "c\\\\d", "e\\f g", "h\"i", "j\\\"k", "lmn", "o", "pqr", "st \"u", "\\v" }; @@ -299,7 +303,7 @@ TEST(CommandLineTest, SetValueInSubcategories) { EXPECT_FALSE(SC1Opt); EXPECT_FALSE(SC2Opt); const char *args[] = {"prog", "-top-level"}; - EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, StringRef(), true)); EXPECT_TRUE(TopLevelOpt); EXPECT_FALSE(SC1Opt); EXPECT_FALSE(SC2Opt); @@ -311,7 +315,7 @@ TEST(CommandLineTest, SetValueInSubcategories) { EXPECT_FALSE(SC1Opt); EXPECT_FALSE(SC2Opt); const char *args2[] = {"prog", "sc1", "-sc1"}; - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, StringRef(), true)); EXPECT_FALSE(TopLevelOpt); EXPECT_TRUE(SC1Opt); EXPECT_FALSE(SC2Opt); @@ -323,7 +327,7 @@ TEST(CommandLineTest, SetValueInSubcategories) { EXPECT_FALSE(SC1Opt); EXPECT_FALSE(SC2Opt); const char *args3[] = {"prog", "sc2", "-sc2"}; - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, StringRef(), true)); EXPECT_FALSE(TopLevelOpt); EXPECT_FALSE(SC1Opt); EXPECT_TRUE(SC2Opt); @@ -339,7 +343,7 @@ TEST(CommandLineTest, LookupFailsInWrongSubCommand) { StackOption<bool> SC2Opt("sc2", cl::sub(SC2), cl::init(false)); const char *args[] = {"prog", "sc1", "-sc2"}; - EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, nullptr, true)); + EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, StringRef(), true)); } TEST(CommandLineTest, AddToAllSubCommands) { @@ -355,21 +359,21 @@ TEST(CommandLineTest, AddToAllSubCommands) { const char *args3[] = {"prog", "sc2", "-everywhere"}; EXPECT_FALSE(AllOpt); - EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, StringRef(), true)); EXPECT_TRUE(AllOpt); AllOpt = false; cl::ResetAllOptionOccurrences(); EXPECT_FALSE(AllOpt); - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, StringRef(), true)); EXPECT_TRUE(AllOpt); AllOpt = false; cl::ResetAllOptionOccurrences(); EXPECT_FALSE(AllOpt); - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, StringRef(), true)); EXPECT_TRUE(AllOpt); } @@ -382,14 +386,14 @@ TEST(CommandLineTest, ReparseCommandLineOptions) { const char *args[] = {"prog", "-top-level"}; EXPECT_FALSE(TopLevelOpt); - EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, StringRef(), true)); EXPECT_TRUE(TopLevelOpt); TopLevelOpt = false; cl::ResetAllOptionOccurrences(); EXPECT_FALSE(TopLevelOpt); - EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, StringRef(), true)); EXPECT_TRUE(TopLevelOpt); } @@ -403,13 +407,13 @@ TEST(CommandLineTest, RemoveFromRegularSubCommand) { const char *args[] = {"prog", "sc", "-remove-option"}; EXPECT_FALSE(RemoveOption); - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args, StringRef(), true)); EXPECT_TRUE(RemoveOption); RemoveOption.removeArgument(); cl::ResetAllOptionOccurrences(); - EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, nullptr, true)); + EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, StringRef(), true)); } TEST(CommandLineTest, RemoveFromTopLevelSubCommand) { @@ -423,13 +427,13 @@ TEST(CommandLineTest, RemoveFromTopLevelSubCommand) { const char *args[] = {"prog", "-top-level-remove"}; EXPECT_FALSE(TopLevelRemove); - EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, StringRef(), true)); EXPECT_TRUE(TopLevelRemove); TopLevelRemove.removeArgument(); cl::ResetAllOptionOccurrences(); - EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, nullptr, true)); + EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, StringRef(), true)); } TEST(CommandLineTest, RemoveFromAllSubCommands) { @@ -448,32 +452,122 @@ TEST(CommandLineTest, RemoveFromAllSubCommands) { // It should work for all subcommands including the top-level. EXPECT_FALSE(RemoveOption); - EXPECT_TRUE(cl::ParseCommandLineOptions(2, args0, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args0, StringRef(), true)); EXPECT_TRUE(RemoveOption); RemoveOption = false; cl::ResetAllOptionOccurrences(); EXPECT_FALSE(RemoveOption); - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args1, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args1, StringRef(), true)); EXPECT_TRUE(RemoveOption); RemoveOption = false; cl::ResetAllOptionOccurrences(); EXPECT_FALSE(RemoveOption); - EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true)); + EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, StringRef(), true)); EXPECT_TRUE(RemoveOption); RemoveOption.removeArgument(); // It should not work for any subcommands including the top-level. cl::ResetAllOptionOccurrences(); - EXPECT_FALSE(cl::ParseCommandLineOptions(2, args0, nullptr, true)); + EXPECT_FALSE(cl::ParseCommandLineOptions(2, args0, StringRef(), true)); cl::ResetAllOptionOccurrences(); - EXPECT_FALSE(cl::ParseCommandLineOptions(3, args1, nullptr, true)); + EXPECT_FALSE(cl::ParseCommandLineOptions(3, args1, StringRef(), true)); cl::ResetAllOptionOccurrences(); - EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, nullptr, true)); + EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, StringRef(), true)); +} + +TEST(CommandLineTest, GetRegisteredSubcommands) { + cl::ResetCommandLineParser(); + + StackSubCommand SC1("sc1", "First Subcommand"); + StackOption<bool> Opt1("opt1", cl::sub(SC1), cl::init(false)); + StackSubCommand SC2("sc2", "Second subcommand"); + StackOption<bool> Opt2("opt2", cl::sub(SC2), cl::init(false)); + + const char *args0[] = {"prog", "sc1"}; + const char *args1[] = {"prog", "sc2"}; + + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args0, StringRef(), true)); + EXPECT_FALSE(Opt1); + EXPECT_FALSE(Opt2); + for (auto *S : cl::getRegisteredSubcommands()) { + if (*S) + EXPECT_EQ("sc1", S->getName()); + } + + cl::ResetAllOptionOccurrences(); + EXPECT_TRUE(cl::ParseCommandLineOptions(2, args1, StringRef(), true)); + EXPECT_FALSE(Opt1); + EXPECT_FALSE(Opt2); + for (auto *S : cl::getRegisteredSubcommands()) { + if (*S) + EXPECT_EQ("sc2", S->getName()); + } +} + +TEST(CommandLineTest, ResponseFiles) { + llvm::SmallString<128> TestDir; + std::error_code EC = + llvm::sys::fs::createUniqueDirectory("unittest", TestDir); + EXPECT_TRUE(!EC); + + // Create included response file of first level. + llvm::SmallString<128> IncludedFileName; + llvm::sys::path::append(IncludedFileName, TestDir, "resp1"); + std::ofstream IncludedFile(IncludedFileName.c_str()); + EXPECT_TRUE(IncludedFile.is_open()); + IncludedFile << "-option_1 -option_2\n" + "@incdir/resp2\n" + "-option_3=abcd\n"; + IncludedFile.close(); + + // Directory for included file. + llvm::SmallString<128> IncDir; + llvm::sys::path::append(IncDir, TestDir, "incdir"); + EC = llvm::sys::fs::create_directory(IncDir); + EXPECT_TRUE(!EC); + + // Create included response file of second level. + llvm::SmallString<128> IncludedFileName2; + llvm::sys::path::append(IncludedFileName2, IncDir, "resp2"); + std::ofstream IncludedFile2(IncludedFileName2.c_str()); + EXPECT_TRUE(IncludedFile2.is_open()); + IncludedFile2 << "-option_21 -option_22\n"; + IncludedFile2 << "-option_23=abcd\n"; + IncludedFile2.close(); + + // Prepare 'file' with reference to response file. + SmallString<128> IncRef; + IncRef.append(1, '@'); + IncRef.append(IncludedFileName.c_str()); + llvm::SmallVector<const char *, 4> Argv = + { "test/test", "-flag_1", IncRef.c_str(), "-flag_2" }; + + // Expand response files. + llvm::BumpPtrAllocator A; + llvm::StringSaver Saver(A); + bool Res = llvm::cl::ExpandResponseFiles( + Saver, llvm::cl::TokenizeGNUCommandLine, Argv, false, true); + EXPECT_TRUE(Res); + EXPECT_EQ(Argv.size(), 9U); + EXPECT_STREQ(Argv[0], "test/test"); + EXPECT_STREQ(Argv[1], "-flag_1"); + EXPECT_STREQ(Argv[2], "-option_1"); + EXPECT_STREQ(Argv[3], "-option_2"); + EXPECT_STREQ(Argv[4], "-option_21"); + EXPECT_STREQ(Argv[5], "-option_22"); + EXPECT_STREQ(Argv[6], "-option_23=abcd"); + EXPECT_STREQ(Argv[7], "-option_3=abcd"); + EXPECT_STREQ(Argv[8], "-flag_2"); + + llvm::sys::fs::remove(IncludedFileName2); + llvm::sys::fs::remove(IncDir); + llvm::sys::fs::remove(IncludedFileName); + llvm::sys::fs::remove(TestDir); } } // anonymous namespace |