[pkg-d-commits] [ldc] 24/149: Improve support for response files in command line (#1942)
Matthias Klumpp
mak at moszumanska.debian.org
Sun Apr 23 22:36:54 UTC 2017
This is an automated email from the git hooks/post-receive script.
mak pushed a commit to annotated tag v1.2.0
in repository ldc.
commit b7e576d5796d749c2c32b7b9996726a730a55479
Author: kinke <kinke at users.noreply.github.com>
Date: Wed Jan 4 23:58:15 2017 +0100
Improve support for response files in command line (#1942)
Fix issue #1941 by expanding response files *before* temptatively parsing
an explicit `-conf` and/or target triple for the config file lookup.
After injecting the switches from the config file right after argv[0],
expand again to catch any response files specified in the config file
switches.
---
driver/main.cpp | 107 +++++++++++++++++++++++++++---------------------
tests/driver/gh1941.d | 4 ++
tests/driver/gh1941.rsp | 1 +
3 files changed, 65 insertions(+), 47 deletions(-)
diff --git a/driver/main.cpp b/driver/main.cpp
index 485f11b..79b882c 100644
--- a/driver/main.cpp
+++ b/driver/main.cpp
@@ -231,48 +231,50 @@ void initFromPathString(const char *&dest, const cl::opt<std::string> &src) {
}
}
-const char *tryGetExplicitConfFile(int argc, char **argv) {
- // begin at the back => use latest -conf= specification
- for (int i = argc - 1; i >= 1; --i) {
- if (strncmp(argv[i], "-conf=", 6) == 0) {
- return argv[i] + 6;
- }
- }
- return nullptr;
-}
-
template <int N> // option length incl. terminating null
-void tryParse(int argc, char **argv, int i, const char *&output,
- const char (&option)[N]) {
- if (strncmp(argv[i], option, N - 1) != 0)
+void tryParse(const llvm::SmallVectorImpl<const char *> &args, size_t i,
+ const char *&output, const char (&option)[N]) {
+ if (strncmp(args[i], option, N - 1) != 0)
return;
- char nextChar = argv[i][N - 1];
+ char nextChar = args[i][N - 1];
if (nextChar == '=')
- output = argv[i] + N;
- else if (nextChar == 0 && i < argc - 1)
- output = argv[i + 1];
+ output = args[i] + N;
+ else if (nextChar == 0 && i < args.size() - 1)
+ output = args[i + 1];
}
-llvm::Triple tryGetExplicitTriple(int argc, char **argv) {
+const char *
+tryGetExplicitConfFile(const llvm::SmallVectorImpl<const char *> &args) {
+ const char *conf = nullptr;
+ // begin at the back => use latest -conf specification
+ assert(args.size() >= 1);
+ for (size_t i = args.size() - 1; !conf && i >= 1; --i) {
+ tryParse(args, i, conf, "-conf");
+ }
+ return conf;
+}
+
+llvm::Triple
+tryGetExplicitTriple(const llvm::SmallVectorImpl<const char *> &args) {
// most combinations of flags are illegal, this mimicks command line
// behaviour for legal ones only
llvm::Triple triple(llvm::sys::getDefaultTargetTriple());
const char *mtriple = nullptr;
const char *march = nullptr;
- for (int i = 1; i < argc; ++i) {
- if (sizeof(void *) != 4 && strcmp(argv[i], "-m32") == 0) {
+ for (size_t i = 1; i < args.size(); ++i) {
+ if (sizeof(void *) != 4 && strcmp(args[i], "-m32") == 0) {
triple = triple.get32BitArchVariant();
if (triple.getArch() == llvm::Triple::ArchType::x86)
triple.setArchName("i686"); // instead of i386
return triple;
}
- if (sizeof(void *) != 8 && strcmp(argv[i], "-m64") == 0)
+ if (sizeof(void *) != 8 && strcmp(args[i], "-m64") == 0)
return triple.get64BitArchVariant();
- tryParse(argc, argv, i, mtriple, "-mtriple");
- tryParse(argc, argv, i, march, "-march");
+ tryParse(args, i, mtriple, "-mtriple");
+ tryParse(args, i, march, "-march");
}
if (mtriple)
triple = llvm::Triple(llvm::Triple::normalize(mtriple));
@@ -283,6 +285,21 @@ llvm::Triple tryGetExplicitTriple(int argc, char **argv) {
return triple;
}
+void expandResponseFiles(llvm::BumpPtrAllocator &A,
+ llvm::SmallVectorImpl<const char *> &args) {
+#if LDC_LLVM_VER >= 308
+ llvm::StringSaver Saver(A);
+ cl::ExpandResponseFiles(Saver,
+#ifdef _WIN32
+ cl::TokenizeWindowsCommandLine
+#else
+ cl::TokenizeGNUCommandLine
+#endif
+ ,
+ args);
+#endif
+}
+
/// Parses switches from the command line, any response files and the global
/// config file and sets up global.params accordingly.
///
@@ -304,41 +321,37 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,
global.params.moduleDeps = nullptr;
global.params.moduleDepsFile = nullptr;
- // Build combined list of command line arguments.
- opts::allArguments.push_back(argv[0]);
+ // Set up `opts::allArguments`, the combined list of command line arguments.
+ using opts::allArguments;
+
+ // initialize with the actual command line
+ allArguments.insert(allArguments.end(), argv, argv + argc);
+
+ // expand response files (`@<file>`) in-place
+ llvm::BumpPtrAllocator allocator;
+ expandResponseFiles(allocator, allArguments);
+ // read config file
ConfigFile cfg_file;
- const char *explicitConfFile = tryGetExplicitConfFile(argc, argv);
- const std::string cfg_triple = tryGetExplicitTriple(argc, argv).getTriple();
+ const char *explicitConfFile = tryGetExplicitConfFile(allArguments);
+ const std::string cfg_triple = tryGetExplicitTriple(allArguments).getTriple();
// just ignore errors for now, they are still printed
cfg_file.read(explicitConfFile, cfg_triple.c_str());
- opts::allArguments.insert(opts::allArguments.end(), cfg_file.switches_begin(),
- cfg_file.switches_end());
- opts::allArguments.insert(opts::allArguments.end(), &argv[1], &argv[argc]);
+ // insert switches from config file before all explicit ones
+ allArguments.insert(allArguments.begin() + 1, cfg_file.switches_begin(),
+ cfg_file.switches_end());
+
+ // finalize by expanding response files specified in config file
+ expandResponseFiles(allocator, allArguments);
cl::SetVersionPrinter(&printVersion);
opts::hideLLVMOptions();
opts::createClashingOptions();
-// pre-expand response files (LLVM's ParseCommandLineOptions() always uses
-// TokenizeGNUCommandLine which eats backslashes)
-#if LDC_LLVM_VER >= 308
- llvm::BumpPtrAllocator A;
- llvm::StringSaver Saver(A);
- cl::ExpandResponseFiles(Saver,
-#ifdef _WIN32
- cl::TokenizeWindowsCommandLine
-#else
- cl::TokenizeGNUCommandLine
-#endif
- ,
- opts::allArguments);
-#endif
-
- cl::ParseCommandLineOptions(opts::allArguments.size(),
- const_cast<char **>(opts::allArguments.data()),
+ cl::ParseCommandLineOptions(allArguments.size(),
+ const_cast<char **>(allArguments.data()),
"LDC - the LLVM D compiler\n");
helpOnly = mCPU == "help" ||
diff --git a/tests/driver/gh1941.d b/tests/driver/gh1941.d
new file mode 100644
index 0000000..2bfb930
--- /dev/null
+++ b/tests/driver/gh1941.d
@@ -0,0 +1,4 @@
+// REQUIRES: atleast_llvm308
+// RUN: %ldc -c %s @%S/gh1941.rsp 2>&1 | FileCheck %s
+
+// CHECK: 'foo.conf' not found
diff --git a/tests/driver/gh1941.rsp b/tests/driver/gh1941.rsp
new file mode 100644
index 0000000..f577217
--- /dev/null
+++ b/tests/driver/gh1941.rsp
@@ -0,0 +1 @@
+-conf=foo.conf
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-d/ldc.git
More information about the pkg-d-commits
mailing list