Some systems, such as certain variants of Microsoft Windows and
+some older Unices have a relatively low limit on command-line
+length. It is therefore customary to use the so-called 'response
+files' to circumvent this restriction. These files are mentioned on
+the command-line (using the "@file") syntax. The program reads these
+files and inserts the contents into argv, thereby working around the
+command-line length limits. Response files are enabled by an optional
+fourth argument to
+cl::ParseEnvironmentOptions
+and
+cl::ParseCommandLineOptions.
+
The cl::ParseCommandLineOptions function requires two parameters
(argc and argv), but may also take an optional third parameter
which holds additional extra text to emit when the
---help option is invoked.
+--help option is invoked, and a fourth boolean parameter that enables
+response files.
It takes three parameters: the name of the program (since argv may
+
It takes four parameters: the name of the program (since argv may
not be available, it can't just look in argv[0]), the name of the
-environment variable to examine, and the optional
+environment variable to examine, the optional
additional extra text to emit when the
---help option is invoked.
+--help option is invoked, and the boolean
+switch that controls whether reponse files
+should be read.
cl::ParseEnvironmentOptions will break the environment
variable's value up into words and then process them using
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 0f804395c39..27782c875ff 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -41,14 +41,16 @@ namespace cl {
// ParseCommandLineOptions - Command line option processing entry point.
//
void ParseCommandLineOptions(int argc, char **argv,
- const char *Overview = 0);
+ const char *Overview = 0,
+ bool ReadResponseFiles = false);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
// entry point.
//
void ParseEnvironmentOptions(const char *progName, const char *envvar,
- const char *Overview = 0);
+ const char *Overview = 0,
+ bool ReadResponseFiles = false);
///===---------------------------------------------------------------------===//
/// SetVersionPrinter - Override the default (LLVM specific) version printer
@@ -146,10 +148,10 @@ class Option {
virtual enum ValueExpected getValueExpectedFlagDefault() const {
return ValueOptional;
}
-
+
// Out of line virtual function to provide home for the class.
virtual void anchor();
-
+
int NumOccurrences; // The number of times specified
int Flags; // Flags for the argument
unsigned Position; // Position of last occurrence of the option
@@ -213,7 +215,7 @@ public:
// addArgument - Register this argument with the commandline system.
//
void addArgument();
-
+
Option *getNextRegisteredOption() const { return NextRegistered; }
// Return the width of the option tag for printing...
@@ -225,7 +227,7 @@ public:
virtual void printOptionInfo(unsigned GlobalWidth) const = 0;
virtual void getExtraOptionNames(std::vector &OptionNames) {}
-
+
// addOccurrence - Wrapper around handleOccurrence that enforces Flags
//
bool addOccurrence(unsigned pos, const char *ArgName,
@@ -339,7 +341,7 @@ public:
};
template
-ValuesClass END_WITH_NULL values(const char *Arg, DataType Val,
+ValuesClass END_WITH_NULL values(const char *Arg, DataType Val,
const char *Desc, ...) {
va_list ValueArgs;
va_start(ValueArgs, Desc);
@@ -389,7 +391,7 @@ struct generic_parser_base {
//
hasArgStr = O.hasArgStr();
}
-
+
void getExtraOptionNames(std::vector &OptionNames) {
// If there has been no argstr specified, that means that we need to add an
// argument for every possible option. This ensures that our options are
@@ -537,7 +539,7 @@ public:
// getValueName - Do not print = at all.
virtual const char *getValueName() const { return 0; }
-
+
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
};
@@ -551,7 +553,7 @@ template<>
class parser : public basic_parser {
public:
// parse - Return true on error.
- bool parse(Option &O, const char *ArgName, const std::string &Arg,
+ bool parse(Option &O, const char *ArgName, const std::string &Arg,
boolOrDefault &Val);
enum ValueExpected getValueExpectedFlagDefault() const {
@@ -560,7 +562,7 @@ public:
// getValueName - Do not print = at all.
virtual const char *getValueName() const { return 0; }
-
+
// An out-of-line virtual method to provide a 'home' for this class.
virtual void anchor();
};
@@ -965,7 +967,7 @@ class list : public Option, public list_storage {
virtual void getExtraOptionNames(std::vector &OptionNames) {
return Parser.getExtraOptionNames(OptionNames);
}
-
+
virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) {
typename ParserClass::parser_data_type Val =
@@ -1071,7 +1073,7 @@ public:
template
class bits_storage {
unsigned *Location; // Where to store the bits...
-
+
template
static unsigned Bit(const T &V) {
unsigned BitPos = reinterpret_cast(V);
@@ -1096,9 +1098,9 @@ public:
"line option with external storage!");
*Location |= Bit(V);
}
-
+
unsigned getBits() { return *Location; }
-
+
template
bool isSet(const T &V) {
return (*Location & Bit(V)) != 0;
@@ -1106,13 +1108,13 @@ public:
};
-// Define how to hold bits. Since we can inherit from a class, we do so.
+// Define how to hold bits. Since we can inherit from a class, we do so.
// This makes us exactly compatible with the bits in all cases that it is used.
//
template
class bits_storage {
unsigned Bits; // Where to store the bits...
-
+
template
static unsigned Bit(const T &V) {
unsigned BitPos = reinterpret_cast(V);
@@ -1120,15 +1122,15 @@ class bits_storage {
"enum exceeds width of bit vector!");
return 1 << BitPos;
}
-
+
public:
template
void addValue(const T &V) {
Bits |= Bit(V);
}
-
+
unsigned getBits() { return Bits; }
-
+
template
bool isSet(const T &V) {
return (Bits & Bit(V)) != 0;
@@ -1151,7 +1153,7 @@ class bits : public Option, public bits_storage {
virtual void getExtraOptionNames(std::vector &OptionNames) {
return Parser.getExtraOptionNames(OptionNames);
}
-
+
virtual bool handleOccurrence(unsigned pos, const char *ArgName,
const std::string &Arg) {
typename ParserClass::parser_data_type Val =
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 24f220d5136..f4594610dff 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -17,7 +17,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Streams.h"
#include "llvm/System/Path.h"
@@ -87,7 +89,7 @@ static Option *RegisteredOptionList = 0;
void Option::addArgument() {
assert(NextRegistered == 0 && "argument multiply registered!");
-
+
NextRegistered = RegisteredOptionList;
RegisteredOptionList = this;
MarkOptionsChanged();
@@ -111,7 +113,7 @@ static void GetOptionInfo(std::vector