From 430c7ff73297e8a6cb7391debe6b96a6cfa3806e Mon Sep 17 00:00:00 2001 From: Dmitry Mikulin Date: Mon, 5 Mar 2018 19:34:33 +0000 Subject: [PATCH] On Windows we need to be able to process response files with Windows-style path names. Differential Revision: https://reviews.llvm.org/D43988 llvm-svn: 326737 --- llvm/lib/Support/CommandLine.cpp | 6 ++++- llvm/unittests/Support/CommandLineTest.cpp | 35 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index d95b791..1354e3e 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" #include "llvm/Support/ConvertUTF.h" @@ -1080,7 +1081,10 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, SmallVector newArgv(argv, argv + argc); BumpPtrAllocator A; StringSaver Saver(A); - ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv); + ExpandResponseFiles(Saver, + Triple(sys::getProcessTriple()).isOSWindows() ? + cl::TokenizeWindowsCommandLine : cl::TokenizeGNUCommandLine, + newArgv); argv = &newArgv[0]; argc = static_cast(newArgv.size()); diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp index 36ff4e2..328dfa3 100644 --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -10,6 +10,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Triple.h" #include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" @@ -631,6 +632,40 @@ TEST(CommandLineTest, ArgumentLimit) { EXPECT_FALSE(llvm::sys::commandLineFitsWithinSystemLimits("cl", args.data())); } +TEST(CommandLineTest, ResponseFileWindows) { + if (!Triple(sys::getProcessTriple()).isOSWindows()) + return; + + static cl::list + InputFilenames(cl::Positional, cl::desc(""), cl::ZeroOrMore); + StackOption TopLevelOpt("top-level", cl::init(false)); + + // Create response file. + int FileDescriptor; + SmallString<64> TempPath; + std::error_code EC = + llvm::sys::fs::createTemporaryFile("resp-", ".txt", FileDescriptor, TempPath); + EXPECT_TRUE(!EC); + + std::ofstream RspFile(TempPath.c_str()); + EXPECT_TRUE(RspFile.is_open()); + RspFile << "-top-level\npath\\dir\\file1\npath/dir/file2"; + RspFile.close(); + + llvm::SmallString<128> RspOpt; + RspOpt.append(1, '@'); + RspOpt.append(TempPath.c_str()); + const char *args[] = {"prog", RspOpt.c_str()}; + EXPECT_FALSE(TopLevelOpt); + EXPECT_TRUE( + cl::ParseCommandLineOptions(2, args, StringRef(), &llvm::nulls())); + EXPECT_TRUE(TopLevelOpt); + EXPECT_TRUE(InputFilenames[0] == "path\\dir\\file1"); + EXPECT_TRUE(InputFilenames[1] == "path/dir/file2"); + + llvm::sys::fs::remove(TempPath.c_str()); +} + TEST(CommandLineTest, ResponseFiles) { llvm::SmallString<128> TestDir; std::error_code EC = -- 2.7.4