From 6ac8e034f654db00a7eb680f8ee91839ed9c5b5a Mon Sep 17 00:00:00 2001 From: Serge Pavlov Date: Tue, 1 Nov 2016 06:53:29 +0000 Subject: Allow resolving response file names relative to including file If a response file included by construct @file itself includes a response file and that file is specified by relative file name, current behavior is to resolve the name relative to the current working directory. The change adds additional flag to ExpandResponseFiles that may be used to resolve nested response file names relative to including file. With the new mode a set of related response files may be kept together and reference each other with short position independent names. Differential Revision: https://reviews.llvm.org/D24917 llvm-svn: 285675 --- llvm/unittests/Support/CommandLineTest.cpp | 65 ++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'llvm/unittests/Support/CommandLineTest.cpp') diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index 72c9e32..e061325 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/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 #include #include @@ -505,4 +509,65 @@ TEST(CommandLineTest, GetRegisteredSubcommands) { } } +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 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(), 9); + 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 -- cgit v1.1