mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-03 14:31:10 +00:00
Add support for response files to the CommandLine library.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50355 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2810d675f8
commit
beb4d8293d
@ -52,6 +52,7 @@
|
|||||||
specified</a></li>
|
specified</a></li>
|
||||||
<li><a href="#formatting">Controlling other formatting options</a></li>
|
<li><a href="#formatting">Controlling other formatting options</a></li>
|
||||||
<li><a href="#misc">Miscellaneous option modifiers</a></li>
|
<li><a href="#misc">Miscellaneous option modifiers</a></li>
|
||||||
|
<li><a href="#response">Response files</a></li>
|
||||||
</ul></li>
|
</ul></li>
|
||||||
|
|
||||||
<li><a href="#toplevel">Top-Level Classes and Functions</a>
|
<li><a href="#toplevel">Top-Level Classes and Functions</a>
|
||||||
@ -1442,6 +1443,29 @@ only makes sense with a <a href="#cl::list">cl::list</a> option.</li>
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- _______________________________________________________________________ -->
|
||||||
|
<div class="doc_subsubsection">
|
||||||
|
<a name="response">Response files</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="doc_text">
|
||||||
|
|
||||||
|
<p>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
|
||||||
|
<a href="#cl::ParseEnvironmentOptions"><tt>cl::ParseEnvironmentOptions</tt></a>
|
||||||
|
and
|
||||||
|
<a href="#cl::ParseCommandLineOptions"><tt>cl::ParseCommandLineOptions</tt></a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<!-- ======================================================================= -->
|
<!-- ======================================================================= -->
|
||||||
<div class="doc_subsection">
|
<div class="doc_subsection">
|
||||||
<a name="toplevel">Top-Level Classes and Functions</a>
|
<a name="toplevel">Top-Level Classes and Functions</a>
|
||||||
@ -1475,7 +1499,8 @@ available.</p>
|
|||||||
<p>The <tt>cl::ParseCommandLineOptions</tt> function requires two parameters
|
<p>The <tt>cl::ParseCommandLineOptions</tt> function requires two parameters
|
||||||
(<tt>argc</tt> and <tt>argv</tt>), but may also take an optional third parameter
|
(<tt>argc</tt> and <tt>argv</tt>), but may also take an optional third parameter
|
||||||
which holds <a href="#description">additional extra text</a> to emit when the
|
which holds <a href="#description">additional extra text</a> to emit when the
|
||||||
<tt>--help</tt> option is invoked.</p>
|
<tt>--help</tt> option is invoked, and a fourth boolean parameter that enables
|
||||||
|
<a href="#response">response files</a>.</p>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -1497,11 +1522,13 @@ like <a
|
|||||||
href="#cl::ParseCommandLineOptions"><tt>cl::ParseCommandLineOptions</tt></a>
|
href="#cl::ParseCommandLineOptions"><tt>cl::ParseCommandLineOptions</tt></a>
|
||||||
does.</p>
|
does.</p>
|
||||||
|
|
||||||
<p>It takes three parameters: the name of the program (since <tt>argv</tt> may
|
<p>It takes four parameters: the name of the program (since <tt>argv</tt> may
|
||||||
not be available, it can't just look in <tt>argv[0]</tt>), the name of the
|
not be available, it can't just look in <tt>argv[0]</tt>), the name of the
|
||||||
environment variable to examine, and the optional
|
environment variable to examine, the optional
|
||||||
<a href="#description">additional extra text</a> to emit when the
|
<a href="#description">additional extra text</a> to emit when the
|
||||||
<tt>--help</tt> option is invoked.</p>
|
<tt>--help</tt> option is invoked, and the boolean
|
||||||
|
switch that controls whether <a href="#response">reponse files</a>
|
||||||
|
should be read.</p>
|
||||||
|
|
||||||
<p><tt>cl::ParseEnvironmentOptions</tt> will break the environment
|
<p><tt>cl::ParseEnvironmentOptions</tt> will break the environment
|
||||||
variable's value up into words and then process them using
|
variable's value up into words and then process them using
|
||||||
|
@ -41,14 +41,16 @@ namespace cl {
|
|||||||
// ParseCommandLineOptions - Command line option processing entry point.
|
// ParseCommandLineOptions - Command line option processing entry point.
|
||||||
//
|
//
|
||||||
void ParseCommandLineOptions(int argc, char **argv,
|
void ParseCommandLineOptions(int argc, char **argv,
|
||||||
const char *Overview = 0);
|
const char *Overview = 0,
|
||||||
|
bool ReadResponseFiles = false);
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ParseEnvironmentOptions - Environment variable option processing alternate
|
// ParseEnvironmentOptions - Environment variable option processing alternate
|
||||||
// entry point.
|
// entry point.
|
||||||
//
|
//
|
||||||
void ParseEnvironmentOptions(const char *progName, const char *envvar,
|
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
|
/// SetVersionPrinter - Override the default (LLVM specific) version printer
|
||||||
|
@ -17,7 +17,9 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "llvm/Config/config.h"
|
#include "llvm/Config/config.h"
|
||||||
|
#include "llvm/ADT/OwningPtr.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
#include "llvm/Support/ManagedStatic.h"
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
#include "llvm/Support/Streams.h"
|
#include "llvm/Support/Streams.h"
|
||||||
#include "llvm/System/Path.h"
|
#include "llvm/System/Path.h"
|
||||||
@ -309,7 +311,7 @@ static void ParseCStringVector(std::vector<char *> &output,
|
|||||||
/// an environment variable (whose name is given in ENVVAR).
|
/// an environment variable (whose name is given in ENVVAR).
|
||||||
///
|
///
|
||||||
void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
|
void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
|
||||||
const char *Overview) {
|
const char *Overview, bool ReadResponseFiles) {
|
||||||
// Check args.
|
// Check args.
|
||||||
assert(progName && "Program name not specified");
|
assert(progName && "Program name not specified");
|
||||||
assert(envVar && "Environment variable name missing");
|
assert(envVar && "Environment variable name missing");
|
||||||
@ -328,7 +330,7 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
|
|||||||
// and hand it off to ParseCommandLineOptions().
|
// and hand it off to ParseCommandLineOptions().
|
||||||
ParseCStringVector(newArgv, envValue);
|
ParseCStringVector(newArgv, envValue);
|
||||||
int newArgc = newArgv.size();
|
int newArgc = newArgv.size();
|
||||||
ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
|
ParseCommandLineOptions(newArgc, &newArgv[0], Overview, ReadResponseFiles);
|
||||||
|
|
||||||
// Free all the strdup()ed strings.
|
// Free all the strdup()ed strings.
|
||||||
for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
|
for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
|
||||||
@ -336,8 +338,44 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
|
|||||||
free (*i);
|
free (*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// ExpandResponseFiles - Copy the contents of argv into newArgv,
|
||||||
|
/// substituting the contents of the response files for the arguments
|
||||||
|
/// of type @file.
|
||||||
|
static void ExpandResponseFiles(int argc, char** argv,
|
||||||
|
std::vector<char*>& newArgv) {
|
||||||
|
for (int i = 1; i != argc; ++i) {
|
||||||
|
char* arg = argv[i];
|
||||||
|
|
||||||
|
if (arg[0] == '@') {
|
||||||
|
|
||||||
|
sys::PathWithStatus respFile(++arg);
|
||||||
|
|
||||||
|
// Check that the response file is not empty (mmap'ing empty
|
||||||
|
// files can be problematic).
|
||||||
|
const sys::FileStatus *FileStat = respFile.getFileStatus();
|
||||||
|
if (!FileStat)
|
||||||
|
continue;
|
||||||
|
if (FileStat->getSize() == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Mmap the response file into memory.
|
||||||
|
OwningPtr<MemoryBuffer>
|
||||||
|
respFilePtr(MemoryBuffer::getFile(respFile.c_str()));
|
||||||
|
|
||||||
|
if (respFilePtr == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ParseCStringVector(newArgv, respFilePtr->getBufferStart());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newArgv.push_back(strdup(arg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cl::ParseCommandLineOptions(int argc, char **argv,
|
void cl::ParseCommandLineOptions(int argc, char **argv,
|
||||||
const char *Overview) {
|
const char *Overview, bool ReadResponseFiles) {
|
||||||
// Process all registered options.
|
// Process all registered options.
|
||||||
std::vector<Option*> PositionalOpts;
|
std::vector<Option*> PositionalOpts;
|
||||||
std::vector<Option*> SinkOpts;
|
std::vector<Option*> SinkOpts;
|
||||||
@ -346,6 +384,16 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
|
|||||||
|
|
||||||
assert((!Opts.empty() || !PositionalOpts.empty()) &&
|
assert((!Opts.empty() || !PositionalOpts.empty()) &&
|
||||||
"No options specified!");
|
"No options specified!");
|
||||||
|
|
||||||
|
// Expand response files.
|
||||||
|
std::vector<char*> newArgv;
|
||||||
|
if (ReadResponseFiles) {
|
||||||
|
newArgv.push_back(strdup(argv[0]));
|
||||||
|
ExpandResponseFiles(argc, argv, newArgv);
|
||||||
|
argv = &newArgv[0];
|
||||||
|
argc = newArgv.size();
|
||||||
|
}
|
||||||
|
|
||||||
sys::Path progname(argv[0]);
|
sys::Path progname(argv[0]);
|
||||||
|
|
||||||
// Copy the program name into ProgName, making sure not to overflow it.
|
// Copy the program name into ProgName, making sure not to overflow it.
|
||||||
@ -664,6 +712,14 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
|
|||||||
PositionalOpts.clear();
|
PositionalOpts.clear();
|
||||||
MoreHelp->clear();
|
MoreHelp->clear();
|
||||||
|
|
||||||
|
// Free the memory allocated by ExpandResponseFiles.
|
||||||
|
if (ReadResponseFiles) {
|
||||||
|
// Free all the strdup()ed strings.
|
||||||
|
for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
|
||||||
|
i != e; ++i)
|
||||||
|
free (*i);
|
||||||
|
}
|
||||||
|
|
||||||
// If we had an error processing our arguments, don't let the program execute
|
// If we had an error processing our arguments, don't let the program execute
|
||||||
if (ErrorParsing) exit(1);
|
if (ErrorParsing) exit(1);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user