llvm.org GIT mirror llvm / beb4d82
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 Mikhail Glushenkov 11 years ago
3 changed file(s) with 133 addition(s) and 48 deletion(s). Raw diff Collapse all Expand all
5151 specified
5252
  • Controlling other formatting options
  • 5353
  • Miscellaneous option modifiers
  • 54
  • Response files
  • 5455
    5556
    5657
  • Top-Level Classes and Functions
  • 14411442
    14421443
    14431444
    1445
    1446
    1447 Response files
    1448
    1449
    1450
    1451
    1452

    Some systems, such as certain variants of Microsoft Windows and

    1453 some older Unices have a relatively low limit on command-line
    1454 length. It is therefore customary to use the so-called 'response
    1455 files' to circumvent this restriction. These files are mentioned on
    1456 the command-line (using the "@file") syntax. The program reads these
    1457 files and inserts the contents into argv, thereby working around the
    1458 command-line length limits. Response files are enabled by an optional
    1459 fourth argument to
    1460 cl::ParseEnvironmentOptions
    1461 and
    1462 cl::ParseCommandLineOptions.
    1463

    1464
    1465
    1466
    1467
    14441468
    14451469
    14461470 Top-Level Classes and Functions
    14741498

    The cl::ParseCommandLineOptions function requires two parameters

    14751499 (argc and argv), but may also take an optional third parameter
    14761500 which holds additional extra text to emit when the
    1477 --help option is invoked.

    1501 --help option is invoked, and a fourth boolean parameter that enables
    1502 response files.

    14781503
    14791504
    14801505
    14961521 href="#cl::ParseCommandLineOptions">cl::ParseCommandLineOptions
    14971522 does.

    14981523
    1499

    It takes three parameters: the name of the program (since argv may

    1524

    It takes four parameters: the name of the program (since argv may

    15001525 not be available, it can't just look in argv[0]), the name of the
    1501 environment variable to examine, and the optional
    1526 environment variable to examine, the optional
    15021527 additional extra text to emit when the
    1503 --help option is invoked.

    1528 --help option is invoked, and the boolean
    1529 switch that controls whether reponse files
    1530 should be read.

    15041531
    15051532

    cl::ParseEnvironmentOptions will break the environment

    15061533 variable's value up into words and then process them using
    4040 // ParseCommandLineOptions - Command line option processing entry point.
    4141 //
    4242 void ParseCommandLineOptions(int argc, char **argv,
    43 const char *Overview = 0);
    43 const char *Overview = 0,
    44 bool ReadResponseFiles = false);
    4445
    4546 //===----------------------------------------------------------------------===//
    4647 // ParseEnvironmentOptions - Environment variable option processing alternate
    4748 // entry point.
    4849 //
    4950 void ParseEnvironmentOptions(const char *progName, const char *envvar,
    50 const char *Overview = 0);
    51 const char *Overview = 0,
    52 bool ReadResponseFiles = false);
    5153
    5254 ///===---------------------------------------------------------------------===//
    5355 /// SetVersionPrinter - Override the default (LLVM specific) version printer
    145147 virtual enum ValueExpected getValueExpectedFlagDefault() const {
    146148 return ValueOptional;
    147149 }
    148
    150
    149151 // Out of line virtual function to provide home for the class.
    150152 virtual void anchor();
    151
    153
    152154 int NumOccurrences; // The number of times specified
    153155 int Flags; // Flags for the argument
    154156 unsigned Position; // Position of last occurrence of the option
    212214 // addArgument - Register this argument with the commandline system.
    213215 //
    214216 void addArgument();
    215
    217
    216218 Option *getNextRegisteredOption() const { return NextRegistered; }
    217219
    218220 // Return the width of the option tag for printing...
    224226 virtual void printOptionInfo(unsigned GlobalWidth) const = 0;
    225227
    226228 virtual void getExtraOptionNames(std::vector &OptionNames) {}
    227
    229
    228230 // addOccurrence - Wrapper around handleOccurrence that enforces Flags
    229231 //
    230232 bool addOccurrence(unsigned pos, const char *ArgName,
    338340 };
    339341
    340342 template
    341 ValuesClass END_WITH_NULL values(const char *Arg, DataType Val,
    343 ValuesClass END_WITH_NULL values(const char *Arg, DataType Val,
    342344 const char *Desc, ...) {
    343345 va_list ValueArgs;
    344346 va_start(ValueArgs, Desc);
    388390 //
    389391 hasArgStr = O.hasArgStr();
    390392 }
    391
    393
    392394 void getExtraOptionNames(std::vector &OptionNames) {
    393395 // If there has been no argstr specified, that means that we need to add an
    394396 // argument for every possible option. This ensures that our options are
    536538
    537539 // getValueName - Do not print = at all.
    538540 virtual const char *getValueName() const { return 0; }
    539
    541
    540542 // An out-of-line virtual method to provide a 'home' for this class.
    541543 virtual void anchor();
    542544 };
    550552 class parser : public basic_parser {
    551553 public:
    552554 // parse - Return true on error.
    553 bool parse(Option &O, const char *ArgName, const std::string &Arg,
    555 bool parse(Option &O, const char *ArgName, const std::string &Arg,
    554556 boolOrDefault &Val);
    555557
    556558 enum ValueExpected getValueExpectedFlagDefault() const {
    559561
    560562 // getValueName - Do not print = at all.
    561563 virtual const char *getValueName() const { return 0; }
    562
    564
    563565 // An out-of-line virtual method to provide a 'home' for this class.
    564566 virtual void anchor();
    565567 };
    964966 virtual void getExtraOptionNames(std::vector &OptionNames) {
    965967 return Parser.getExtraOptionNames(OptionNames);
    966968 }
    967
    969
    968970 virtual bool handleOccurrence(unsigned pos, const char *ArgName,
    969971 const std::string &Arg) {
    970972 typename ParserClass::parser_data_type Val =
    10701072 template
    10711073 class bits_storage {
    10721074 unsigned *Location; // Where to store the bits...
    1073
    1075
    10741076 template
    10751077 static unsigned Bit(const T &V) {
    10761078 unsigned BitPos = reinterpret_cast(V);
    10951097 "line option with external storage!");
    10961098 *Location |= Bit(V);
    10971099 }
    1098
    1100
    10991101 unsigned getBits() { return *Location; }
    1100
    1102
    11011103 template
    11021104 bool isSet(const T &V) {
    11031105 return (*Location & Bit(V)) != 0;
    11051107 };
    11061108
    11071109
    1108 // Define how to hold bits. Since we can inherit from a class, we do so.
    1110 // Define how to hold bits. Since we can inherit from a class, we do so.
    11091111 // This makes us exactly compatible with the bits in all cases that it is used.
    11101112 //
    11111113 template
    11121114 class bits_storage {
    11131115 unsigned Bits; // Where to store the bits...
    1114
    1116
    11151117 template
    11161118 static unsigned Bit(const T &V) {
    11171119 unsigned BitPos = reinterpret_cast(V);
    11191121 "enum exceeds width of bit vector!");
    11201122 return 1 << BitPos;
    11211123 }
    1122
    1124
    11231125 public:
    11241126 template
    11251127 void addValue(const T &V) {
    11261128 Bits |= Bit(V);
    11271129 }
    1128
    1130
    11291131 unsigned getBits() { return Bits; }
    1130
    1132
    11311133 template
    11321134 bool isSet(const T &V) {
    11331135 return (Bits & Bit(V)) != 0;
    11501152 virtual void getExtraOptionNames(std::vector &OptionNames) {
    11511153 return Parser.getExtraOptionNames(OptionNames);
    11521154 }
    1153
    1155
    11541156 virtual bool handleOccurrence(unsigned pos, const char *ArgName,
    11551157 const std::string &Arg) {
    11561158 typename ParserClass::parser_data_type Val =
    1616 //===----------------------------------------------------------------------===//
    1717
    1818 #include "llvm/Config/config.h"
    19 #include "llvm/ADT/OwningPtr.h"
    1920 #include "llvm/Support/CommandLine.h"
    21 #include "llvm/Support/MemoryBuffer.h"
    2022 #include "llvm/Support/ManagedStatic.h"
    2123 #include "llvm/Support/Streams.h"
    2224 #include "llvm/System/Path.h"
    8688
    8789 void Option::addArgument() {
    8890 assert(NextRegistered == 0 && "argument multiply registered!");
    89
    91
    9092 NextRegistered = RegisteredOptionList;
    9193 RegisteredOptionList = this;
    9294 MarkOptionsChanged();
    110112 O->getExtraOptionNames(OptionNames);
    111113 if (O->ArgStr[0])
    112114 OptionNames.push_back(O->ArgStr);
    113
    115
    114116 // Handle named options.
    115117 for (unsigned i = 0, e = OptionNames.size(); i != e; ++i) {
    116118 // Add argument to the argument map!
    120122 << OptionNames[0] << "' defined more than once!\n";
    121123 }
    122124 }
    123
    125
    124126 OptionNames.clear();
    125
    127
    126128 // Remember information about positional options.
    127129 if (O->getFormattingFlag() == cl::Positional)
    128130 PositionalOpts.push_back(O);
    134136 CAOpt = O;
    135137 }
    136138 }
    137
    139
    138140 if (CAOpt)
    139141 PositionalOpts.push_back(CAOpt);
    140
    142
    141143 // Make sure that they are in order of registration not backwards.
    142144 std::reverse(PositionalOpts.begin(), PositionalOpts.end());
    143145 }
    149151 static Option *LookupOption(const char *&Arg, const char *&Value,
    150152 std::map &OptionsMap) {
    151153 while (*Arg == '-') ++Arg; // Eat leading dashes
    152
    154
    153155 const char *ArgEnd = Arg;
    154156 while (*ArgEnd && *ArgEnd != '=')
    155157 ++ArgEnd; // Scan till end of argument name.
    156
    158
    157159 if (*ArgEnd == '=') // If we have an equals sign...
    158160 Value = ArgEnd+1; // Get the value, not the equals
    159
    160
    161
    162
    161163 if (*Arg == 0) return 0;
    162
    164
    163165 // Look up the option.
    164166 std::map::iterator I =
    165167 OptionsMap.find(std::string(Arg, ArgEnd));
    308310 /// an environment variable (whose name is given in ENVVAR).
    309311 ///
    310312 void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
    311 const char *Overview) {
    313 const char *Overview, bool ReadResponseFiles) {
    312314 // Check args.
    313315 assert(progName && "Program name not specified");
    314316 assert(envVar && "Environment variable name missing");
    327329 // and hand it off to ParseCommandLineOptions().
    328330 ParseCStringVector(newArgv, envValue);
    329331 int newArgc = newArgv.size();
    330 ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
    332 ParseCommandLineOptions(newArgc, &newArgv[0], Overview, ReadResponseFiles);
    331333
    332334 // Free all the strdup()ed strings.
    333335 for (std::vector::iterator i = newArgv.begin(), e = newArgv.end();
    335337 free (*i);
    336338 }
    337339
    340
    341 /// ExpandResponseFiles - Copy the contents of argv into newArgv,
    342 /// substituting the contents of the response files for the arguments
    343 /// of type @file.
    344 static void ExpandResponseFiles(int argc, char** argv,
    345 std::vector& newArgv) {
    346 for (int i = 1; i != argc; ++i) {
    347 char* arg = argv[i];
    348
    349 if (arg[0] == '@') {
    350
    351 sys::PathWithStatus respFile(++arg);
    352
    353 // Check that the response file is not empty (mmap'ing empty
    354 // files can be problematic).
    355 const sys::FileStatus *FileStat = respFile.getFileStatus();
    356 if (!FileStat)
    357 continue;
    358 if (FileStat->getSize() == 0)
    359 continue;
    360
    361 // Mmap the response file into memory.
    362 OwningPtr
    363 respFilePtr(MemoryBuffer::getFile(respFile.c_str()));
    364
    365 if (respFilePtr == 0)
    366 continue;
    367
    368 ParseCStringVector(newArgv, respFilePtr->getBufferStart());
    369 }
    370 else {
    371 newArgv.push_back(strdup(arg));
    372 }
    373 }
    374 }
    375
    338376 void cl::ParseCommandLineOptions(int argc, char **argv,
    339 const char *Overview) {
    377 const char *Overview, bool ReadResponseFiles) {
    340378 // Process all registered options.
    341379 std::vector PositionalOpts;
    342380 std::vector SinkOpts;
    343381 std::map Opts;
    344382 GetOptionInfo(PositionalOpts, SinkOpts, Opts);
    345
    383
    346384 assert((!Opts.empty() || !PositionalOpts.empty()) &&
    347385 "No options specified!");
    386
    387 // Expand response files.
    388 std::vector newArgv;
    389 if (ReadResponseFiles) {
    390 newArgv.push_back(strdup(argv[0]));
    391 ExpandResponseFiles(argc, argv, newArgv);
    392 argv = &newArgv[0];
    393 argc = newArgv.size();
    394 }
    395
    348396 sys::Path progname(argv[0]);
    349397
    350398 // Copy the program name into ProgName, making sure not to overflow it.
    351399 std::string ProgName = sys::Path(argv[0]).getLast();
    352400 if (ProgName.size() > 79) ProgName.resize(79);
    353401 strcpy(ProgramName, ProgName.c_str());
    354
    402
    355403 ProgramOverview = Overview;
    356404 bool ErrorParsing = false;
    357405
    358406 // Check out the positional arguments to collect information about them.
    359407 unsigned NumPositionalRequired = 0;
    360
    408
    361409 // Determine whether or not there are an unlimited number of positionals
    362410 bool HasUnlimitedPositionals = false;
    363
    411
    364412 Option *ConsumeAfterOpt = 0;
    365413 if (!PositionalOpts.empty()) {
    366414 if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
    426474 GetOptionInfo(PositionalOpts, SinkOpts, Opts);
    427475 OptionListChanged = false;
    428476 }
    429
    477
    430478 // Check to see if this is a positional argument. This argument is
    431479 // considered to be positional if it doesn't start with '-', if it is "-"
    432480 // itself, or if we have seen "--" already.
    566614 << ": Not enough positional command line arguments specified!\n"
    567615 << "Must specify at least " << NumPositionalRequired
    568616 << " positional arguments: See: " << argv[0] << " --help\n";
    569
    617
    570618 ErrorParsing = true;
    571619 } else if (!HasUnlimitedPositionals
    572620 && PositionalVals.size() > PositionalOpts.size()) {
    663711 PositionalOpts.clear();
    664712 MoreHelp->clear();
    665713
    714 // Free the memory allocated by ExpandResponseFiles.
    715 if (ReadResponseFiles) {
    716 // Free all the strdup()ed strings.
    717 for (std::vector::iterator i = newArgv.begin(), e = newArgv.end();
    718 i != e; ++i)
    719 free (*i);
    720 }
    721
    666722 // If we had an error processing our arguments, don't let the program execute
    667723 if (ErrorParsing) exit(1);
    668724 }
    677733 cerr << HelpStr; // Be nice for positional arguments
    678734 else
    679735 cerr << ProgramName << ": for the -" << ArgName;
    680
    736
    681737 cerr << " option: " << Message << "\n";
    682738 return true;
    683739 }
    942998 std::vector SinkOpts;
    943999 std::map OptMap;
    9441000 GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
    945
    1001
    9461002 // Copy Options into a vector so we can sort them as we like...
    9471003 std::vector > Opts;
    9481004 copy(OptMap.begin(), OptMap.end(), std::back_inserter(Opts));
    9691025
    9701026 // Print out the positional options.
    9711027 Option *CAOpt = 0; // The cl::ConsumeAfter option, if it exists...
    972 if (!PositionalOpts.empty() &&
    1028 if (!PositionalOpts.empty() &&
    9731029 PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
    9741030 CAOpt = PositionalOpts[0];
    9751031