forked from OSchip/llvm-project
Implement support for reading arguments specified in a file with @file. If
there is no file named "file", keep the @file option unchanged. llvm-svn: 108697
This commit is contained in:
parent
39c06b3b23
commit
77a067a653
|
@ -0,0 +1,30 @@
|
|||
// RUN: %clang -E %s @%s.args -o %t.log
|
||||
// RUN: FileCheck --input-file=%t.log %s
|
||||
|
||||
// CHECK: bar1
|
||||
// CHECK-NEXT: bar2 zed2
|
||||
// CHECK-NEXT: bar3 zed3
|
||||
// CHECK-NEXT: bar4 zed4
|
||||
// CHECK-NEXT: bar5 zed5
|
||||
// CHECK-NEXT: 'bar6 zed6'
|
||||
// CHECK-NEXT: "bar7 zed7"
|
||||
// CHECK-NEXT: foo8bar8zed8
|
||||
// CHECK-NEXT: foo9'bar9'zed9
|
||||
// CHECK-NEXT: foo10"bar10"zed10
|
||||
// CHECK: bar
|
||||
// CHECK: zed12
|
||||
|
||||
foo1
|
||||
foo2
|
||||
foo3
|
||||
foo4
|
||||
foo5
|
||||
foo6
|
||||
foo7
|
||||
foo8
|
||||
foo9
|
||||
foo10
|
||||
#ifdef foo11
|
||||
bar
|
||||
#endif
|
||||
foo12
|
|
@ -0,0 +1,11 @@
|
|||
-Dfoo1=bar1 -Dfoo2="bar2 zed2"
|
||||
-Dfoo3='bar3 zed3'
|
||||
"-Dfoo4=bar4 zed4"
|
||||
'-Dfoo5=bar5 zed5'
|
||||
-Dfoo6="'bar6 zed6'"
|
||||
-Dfoo7='"bar7 zed7"'
|
||||
-Dfoo8=foo8"bar8"zed8
|
||||
-Dfoo9=foo9\'bar9\'zed9
|
||||
-Dfoo10=foo10\"bar10\"zed10
|
||||
-D foo11
|
||||
-Dfoo12=zed12\
|
|
@ -19,9 +19,12 @@
|
|||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Config/config.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Regex.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
|
@ -173,19 +176,97 @@ extern int cc1_main(const char **ArgBegin, const char **ArgEnd,
|
|||
extern int cc1as_main(const char **ArgBegin, const char **ArgEnd,
|
||||
const char *Argv0, void *MainAddr);
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
static void ExpandArgsFromBuf(const char *Arg,
|
||||
std::vector<const char*> &ArgVector,
|
||||
std::set<std::string> &SavedStrings) {
|
||||
const char *FName = Arg + 1;
|
||||
llvm::MemoryBuffer *MemBuf = llvm::MemoryBuffer::getFile(FName);
|
||||
if (!MemBuf) {
|
||||
ArgVector.push_back(SaveStringInSet(SavedStrings, Arg));
|
||||
return;
|
||||
}
|
||||
|
||||
const char *Buf = MemBuf->getBufferStart();
|
||||
char InQuote = ' ';
|
||||
std::string CurArg;
|
||||
|
||||
for (const char *P = Buf; ; ++P) {
|
||||
if (*P == '\0' || (isspace(*P) && InQuote == ' ')) {
|
||||
if (!CurArg.empty()) {
|
||||
|
||||
if (CurArg[0] != '@') {
|
||||
ArgVector.push_back(SaveStringInSet(SavedStrings, CurArg));
|
||||
} else {
|
||||
ExpandArgsFromBuf(CurArg.c_str(), ArgVector, SavedStrings);
|
||||
}
|
||||
|
||||
CurArg = "";
|
||||
}
|
||||
if (*P == '\0')
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isspace(*P)) {
|
||||
if (InQuote != ' ')
|
||||
CurArg.push_back(*P);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*P == '"' || *P == '\'') {
|
||||
if (InQuote == *P)
|
||||
InQuote = ' ';
|
||||
else if (InQuote == ' ')
|
||||
InQuote = *P;
|
||||
else
|
||||
CurArg.push_back(*P);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (*P == '\\') {
|
||||
++P;
|
||||
if (*P != '\0')
|
||||
CurArg.push_back(*P);
|
||||
continue;
|
||||
}
|
||||
CurArg.push_back(*P);
|
||||
}
|
||||
delete MemBuf;
|
||||
}
|
||||
|
||||
static void ExpandArgv(int argc, const char **argv,
|
||||
std::vector<const char*> &ArgVector,
|
||||
std::set<std::string> &SavedStrings) {
|
||||
for (int i = 0; i < argc; ++i) {
|
||||
const char *Arg = argv[i];
|
||||
if (Arg[0] != '@') {
|
||||
ArgVector.push_back(SaveStringInSet(SavedStrings, std::string(Arg)));
|
||||
continue;
|
||||
}
|
||||
|
||||
ExpandArgsFromBuf(Arg, ArgVector, SavedStrings);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc_, const char **argv_) {
|
||||
llvm::sys::PrintStackTraceOnErrorSignal();
|
||||
llvm::PrettyStackTraceProgram X(argc, argv);
|
||||
llvm::PrettyStackTraceProgram X(argc_, argv_);
|
||||
|
||||
std::set<std::string> SavedStrings;
|
||||
std::vector<const char*> argv;
|
||||
|
||||
ExpandArgv(argc_, argv_, argv, SavedStrings);
|
||||
|
||||
// Handle -cc1 integrated tools.
|
||||
if (argc > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) {
|
||||
if (argv.size() > 1 && llvm::StringRef(argv[1]).startswith("-cc1")) {
|
||||
llvm::StringRef Tool = argv[1] + 4;
|
||||
|
||||
if (Tool == "")
|
||||
return cc1_main(argv+2, argv+argc, argv[0],
|
||||
return cc1_main(&argv[2], &argv[argv.size()], argv[0],
|
||||
(void*) (intptr_t) GetExecutablePath);
|
||||
if (Tool == "as")
|
||||
return cc1as_main(argv+2, argv+argc, argv[0],
|
||||
return cc1as_main(&argv[2], &argv[argv.size()], argv[0],
|
||||
(void*) (intptr_t) GetExecutablePath);
|
||||
|
||||
// Reject unknown tools.
|
||||
|
@ -194,7 +275,7 @@ int main(int argc, const char **argv) {
|
|||
}
|
||||
|
||||
bool CanonicalPrefixes = true;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
for (int i = 1, size = argv.size(); i < size; ++i) {
|
||||
if (llvm::StringRef(argv[i]) == "-no-canonical-prefixes") {
|
||||
CanonicalPrefixes = false;
|
||||
break;
|
||||
|
@ -230,7 +311,8 @@ int main(int argc, const char **argv) {
|
|||
// being a symlink.
|
||||
//
|
||||
// We use *argv instead of argv[0] to work around a bogus g++ warning.
|
||||
std::string ProgName(llvm::sys::Path(*argv).getBasename());
|
||||
const char *progname = argv_[0];
|
||||
std::string ProgName(llvm::sys::Path(progname).getBasename());
|
||||
if (llvm::StringRef(ProgName).endswith("++") ||
|
||||
llvm::StringRef(ProgName).rsplit('-').first.endswith("++")) {
|
||||
TheDriver.CCCIsCXX = true;
|
||||
|
@ -246,34 +328,30 @@ int main(int argc, const char **argv) {
|
|||
|
||||
// Handle QA_OVERRIDE_GCC3_OPTIONS and CCC_ADD_ARGS, used for editing a
|
||||
// command line behind the scenes.
|
||||
std::set<std::string> SavedStrings;
|
||||
std::vector<const char*> StringPointers(argv, argv + argc);
|
||||
if (const char *OverrideStr = ::getenv("QA_OVERRIDE_GCC3_OPTIONS")) {
|
||||
// FIXME: Driver shouldn't take extra initial argument.
|
||||
ApplyQAOverride(StringPointers, OverrideStr, SavedStrings);
|
||||
ApplyQAOverride(argv, OverrideStr, SavedStrings);
|
||||
} else if (const char *Cur = ::getenv("CCC_ADD_ARGS")) {
|
||||
// FIXME: Driver shouldn't take extra initial argument.
|
||||
StringPointers.clear();
|
||||
StringPointers.push_back(argv[0]);
|
||||
std::vector<const char*> ExtraArgs;
|
||||
|
||||
for (;;) {
|
||||
const char *Next = strchr(Cur, ',');
|
||||
|
||||
if (Next) {
|
||||
StringPointers.push_back(SaveStringInSet(SavedStrings,
|
||||
std::string(Cur, Next)));
|
||||
ExtraArgs.push_back(SaveStringInSet(SavedStrings,
|
||||
std::string(Cur, Next)));
|
||||
Cur = Next + 1;
|
||||
} else {
|
||||
if (*Cur != '\0')
|
||||
StringPointers.push_back(SaveStringInSet(SavedStrings, Cur));
|
||||
ExtraArgs.push_back(SaveStringInSet(SavedStrings, Cur));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StringPointers.insert(StringPointers.end(), argv + 1, argv + argc);
|
||||
argv.insert(++argv.begin(), ExtraArgs.begin(), ExtraArgs.end());
|
||||
}
|
||||
C.reset(TheDriver.BuildCompilation(StringPointers.size(),
|
||||
&StringPointers[0]));
|
||||
C.reset(TheDriver.BuildCompilation(argv.size(), &argv[0]));
|
||||
|
||||
int Res = 0;
|
||||
if (C.get())
|
||||
|
|
Loading…
Reference in New Issue