summaryrefslogtreecommitdiff
path: root/unittests/Support/CommandLineTest.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-01-02 19:17:04 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-01-02 19:17:04 +0000
commitb915e9e0fc85ba6f398b3fab0db6a81a8913af94 (patch)
tree98b8f811c7aff2547cab8642daf372d6c59502fb /unittests/Support/CommandLineTest.cpp
parent6421cca32f69ac849537a3cff78c352195e99f1b (diff)
Notes
Diffstat (limited to 'unittests/Support/CommandLineTest.cpp')
-rw-r--r--unittests/Support/CommandLineTest.cpp142
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