mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-13 10:32:06 +00:00
Several changes together in a murky mess:
1. Change some "\n" -> '\n'. 2. eliminte some std::string's by using raw_ostream::indent. 3. move a bunch of code out of the main arg parser routine into a new static HandlePrefixedOrGroupedOption function. 4. Greatly simplify the implementation of getOptionPred, and make it avoid splitting prefix options at = when that doesn't match a non-prefix option. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82362 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3892baac42
commit
b168737a74
@ -150,29 +150,34 @@ static void GetOptionInfo(std::vector<Option*> &PositionalOpts,
|
|||||||
|
|
||||||
/// LookupOption - Lookup the option specified by the specified option on the
|
/// LookupOption - Lookup the option specified by the specified option on the
|
||||||
/// command line. If there is a value specified (after an equal sign) return
|
/// command line. If there is a value specified (after an equal sign) return
|
||||||
/// that as well.
|
/// that as well. This assumes that leading dashes have already been stripped.
|
||||||
static Option *LookupOption(StringRef &Arg, StringRef &Value,
|
static Option *LookupOption(StringRef &Arg, StringRef &Value,
|
||||||
const StringMap<Option*> &OptionsMap) {
|
const StringMap<Option*> &OptionsMap) {
|
||||||
// Eat leading dashes.
|
|
||||||
while (!Arg.empty() && Arg[0] == '-')
|
|
||||||
Arg = Arg.substr(1);
|
|
||||||
|
|
||||||
// Reject all dashes.
|
// Reject all dashes.
|
||||||
if (Arg.empty()) return 0;
|
if (Arg.empty()) return 0;
|
||||||
|
|
||||||
size_t EqualPos = Arg.find('=');
|
size_t EqualPos = Arg.find('=');
|
||||||
|
|
||||||
// If we have an equals sign, remember the value.
|
// If we have an equals sign, remember the value.
|
||||||
if (EqualPos != StringRef::npos) {
|
if (EqualPos == StringRef::npos) {
|
||||||
Value = Arg.substr(EqualPos+1);
|
// Look up the option.
|
||||||
Arg = Arg.substr(0, EqualPos);
|
StringMap<Option*>::const_iterator I = OptionsMap.find(Arg);
|
||||||
|
return I != OptionsMap.end() ? I->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Look up the option.
|
// If the argument before the = is a valid option name, we match. If not,
|
||||||
StringMap<Option*>::const_iterator I = OptionsMap.find(Arg);
|
// return Arg unmolested.
|
||||||
return I != OptionsMap.end() ? I->second : 0;
|
StringMap<Option*>::const_iterator I =
|
||||||
|
OptionsMap.find(Arg.substr(0, EqualPos));
|
||||||
|
if (I == OptionsMap.end()) return 0;
|
||||||
|
|
||||||
|
Value = Arg.substr(EqualPos+1);
|
||||||
|
Arg = Arg.substr(0, EqualPos);
|
||||||
|
return I->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// ProvideOption - For Value, this differentiates between an empty value ("")
|
/// ProvideOption - For Value, this differentiates between an empty value ("")
|
||||||
/// and a null value (StringRef()). The later is accepted for arguments that
|
/// and a null value (StringRef()). The later is accepted for arguments that
|
||||||
/// don't allow a value (-foo) the former is rejected (-foo=).
|
/// don't allow a value (-foo) the former is rejected (-foo=).
|
||||||
@ -260,23 +265,17 @@ static inline bool isPrefixedOrGrouping(const Option *O) {
|
|||||||
//
|
//
|
||||||
static Option *getOptionPred(StringRef Name, size_t &Length,
|
static Option *getOptionPred(StringRef Name, size_t &Length,
|
||||||
bool (*Pred)(const Option*),
|
bool (*Pred)(const Option*),
|
||||||
StringMap<Option*> &OptionsMap) {
|
const StringMap<Option*> &OptionsMap) {
|
||||||
|
|
||||||
StringMap<Option*>::iterator OMI = OptionsMap.find(Name);
|
StringMap<Option*>::const_iterator OMI = OptionsMap.find(Name);
|
||||||
if (OMI != OptionsMap.end() && Pred(OMI->second)) {
|
|
||||||
Length = Name.size();
|
|
||||||
return OMI->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Name.size() == 1) return 0;
|
// Loop while we haven't found an option and Name still has at least two
|
||||||
do {
|
// characters in it (so that the next iteration will not be the empty
|
||||||
|
// string.
|
||||||
|
while (OMI == OptionsMap.end() && Name.size() > 1) {
|
||||||
Name = Name.substr(0, Name.size()-1); // Chop off the last character.
|
Name = Name.substr(0, Name.size()-1); // Chop off the last character.
|
||||||
OMI = OptionsMap.find(Name);
|
OMI = OptionsMap.find(Name);
|
||||||
|
}
|
||||||
// Loop while we haven't found an option and Name still has at least two
|
|
||||||
// characters in it (so that the next iteration will not be the empty
|
|
||||||
// string.
|
|
||||||
} while ((OMI == OptionsMap.end() || !Pred(OMI->second)) && Name.size() > 1);
|
|
||||||
|
|
||||||
if (OMI != OptionsMap.end() && Pred(OMI->second)) {
|
if (OMI != OptionsMap.end() && Pred(OMI->second)) {
|
||||||
Length = Name.size();
|
Length = Name.size();
|
||||||
@ -285,6 +284,57 @@ static Option *getOptionPred(StringRef Name, size_t &Length,
|
|||||||
return 0; // No option found!
|
return 0; // No option found!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HandlePrefixedOrGroupedOption - The specified argument string (which started
|
||||||
|
/// with at least one '-') does not fully match an available option. Check to
|
||||||
|
/// see if this is a prefix or grouped option. If so, split arg into output an
|
||||||
|
/// Arg/Value pair and return the Option to parse it with.
|
||||||
|
static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
|
||||||
|
bool &ErrorParsing,
|
||||||
|
const StringMap<Option*> &OptionsMap) {
|
||||||
|
if (Arg.size() == 1) return 0;
|
||||||
|
|
||||||
|
// Do the lookup!
|
||||||
|
size_t Length = 0;
|
||||||
|
Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);
|
||||||
|
if (PGOpt == 0) return 0;
|
||||||
|
|
||||||
|
// If the option is a prefixed option, then the value is simply the
|
||||||
|
// rest of the name... so fall through to later processing, by
|
||||||
|
// setting up the argument name flags and value fields.
|
||||||
|
if (PGOpt->getFormattingFlag() == cl::Prefix) {
|
||||||
|
Value = Arg.substr(Length);
|
||||||
|
Arg = Arg.substr(0, Length);
|
||||||
|
assert(OptionsMap.count(Arg) && OptionsMap.find(Arg)->second == PGOpt);
|
||||||
|
return PGOpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This must be a grouped option... handle them now. Grouping options can't
|
||||||
|
// have values.
|
||||||
|
assert(isGrouping(PGOpt) && "Broken getOptionPred!");
|
||||||
|
|
||||||
|
do {
|
||||||
|
// Move current arg name out of Arg into OneArgName.
|
||||||
|
StringRef OneArgName = Arg.substr(0, Length);
|
||||||
|
Arg = Arg.substr(Length);
|
||||||
|
|
||||||
|
// Because ValueRequired is an invalid flag for grouped arguments,
|
||||||
|
// we don't need to pass argc/argv in.
|
||||||
|
assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&
|
||||||
|
"Option can not be cl::Grouping AND cl::ValueRequired!");
|
||||||
|
int Dummy;
|
||||||
|
ErrorParsing |= ProvideOption(PGOpt, OneArgName,
|
||||||
|
StringRef(), 0, 0, Dummy);
|
||||||
|
|
||||||
|
// Get the next grouping option.
|
||||||
|
PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);
|
||||||
|
} while (PGOpt && Length != Arg.size());
|
||||||
|
|
||||||
|
// Return the last option with Arg cut down to just the last one.
|
||||||
|
return PGOpt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool RequiresValue(const Option *O) {
|
static bool RequiresValue(const Option *O) {
|
||||||
return O->getNumOccurrencesFlag() == cl::Required ||
|
return O->getNumOccurrencesFlag() == cl::Required ||
|
||||||
O->getNumOccurrencesFlag() == cl::OneOrMore;
|
O->getNumOccurrencesFlag() == cl::OneOrMore;
|
||||||
@ -365,13 +415,12 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
|
|||||||
/// ExpandResponseFiles - Copy the contents of argv into newArgv,
|
/// ExpandResponseFiles - Copy the contents of argv into newArgv,
|
||||||
/// substituting the contents of the response files for the arguments
|
/// substituting the contents of the response files for the arguments
|
||||||
/// of type @file.
|
/// of type @file.
|
||||||
static void ExpandResponseFiles(int argc, char** argv,
|
static void ExpandResponseFiles(unsigned argc, char** argv,
|
||||||
std::vector<char*>& newArgv) {
|
std::vector<char*>& newArgv) {
|
||||||
for (int i = 1; i != argc; ++i) {
|
for (unsigned i = 1; i != argc; ++i) {
|
||||||
char* arg = argv[i];
|
char *arg = argv[i];
|
||||||
|
|
||||||
if (arg[0] == '@') {
|
if (arg[0] == '@') {
|
||||||
|
|
||||||
sys::PathWithStatus respFile(++arg);
|
sys::PathWithStatus respFile(++arg);
|
||||||
|
|
||||||
// Check that the response file is not empty (mmap'ing empty
|
// Check that the response file is not empty (mmap'ing empty
|
||||||
@ -538,6 +587,10 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
|
|||||||
// option is another positional argument. If so, treat it as an argument,
|
// option is another positional argument. If so, treat it as an argument,
|
||||||
// otherwise feed it to the eating positional.
|
// otherwise feed it to the eating positional.
|
||||||
ArgName = argv[i]+1;
|
ArgName = argv[i]+1;
|
||||||
|
// Eat leading dashes.
|
||||||
|
while (!ArgName.empty() && ArgName[0] == '-')
|
||||||
|
ArgName = ArgName.substr(1);
|
||||||
|
|
||||||
Handler = LookupOption(ArgName, Value, Opts);
|
Handler = LookupOption(ArgName, Value, Opts);
|
||||||
if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
|
if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
|
||||||
ProvidePositionalOption(ActivePositionalArg, argv[i], i);
|
ProvidePositionalOption(ActivePositionalArg, argv[i], i);
|
||||||
@ -546,51 +599,16 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
|
|||||||
|
|
||||||
} else { // We start with a '-', must be an argument.
|
} else { // We start with a '-', must be an argument.
|
||||||
ArgName = argv[i]+1;
|
ArgName = argv[i]+1;
|
||||||
|
// Eat leading dashes.
|
||||||
|
while (!ArgName.empty() && ArgName[0] == '-')
|
||||||
|
ArgName = ArgName.substr(1);
|
||||||
|
|
||||||
Handler = LookupOption(ArgName, Value, Opts);
|
Handler = LookupOption(ArgName, Value, Opts);
|
||||||
|
|
||||||
// Check to see if this "option" is really a prefixed or grouped argument.
|
// Check to see if this "option" is really a prefixed or grouped argument.
|
||||||
if (Handler == 0) {
|
if (Handler == 0)
|
||||||
StringRef RealName(ArgName);
|
Handler = HandlePrefixedOrGroupedOption(ArgName, Value,
|
||||||
if (RealName.size() > 1) {
|
ErrorParsing, Opts);
|
||||||
size_t Length = 0;
|
|
||||||
Option *PGOpt =
|
|
||||||
getOptionPred(RealName, Length, isPrefixedOrGrouping, Opts);
|
|
||||||
|
|
||||||
// If the option is a prefixed option, then the value is simply the
|
|
||||||
// rest of the name... so fall through to later processing, by
|
|
||||||
// setting up the argument name flags and value fields.
|
|
||||||
if (PGOpt && PGOpt->getFormattingFlag() == cl::Prefix) {
|
|
||||||
ArgName = argv[i]+1;
|
|
||||||
Value = ArgName.substr(Length);
|
|
||||||
assert(Opts.count(ArgName.substr(0, Length)) &&
|
|
||||||
Opts[ArgName.substr(0, Length)] == PGOpt);
|
|
||||||
Handler = PGOpt;
|
|
||||||
} else if (PGOpt) {
|
|
||||||
// This must be a grouped option... handle them now.
|
|
||||||
assert(isGrouping(PGOpt) && "Broken getOptionPred!");
|
|
||||||
|
|
||||||
do {
|
|
||||||
// Move current arg name out of RealName into RealArgName.
|
|
||||||
StringRef RealArgName = RealName.substr(0, Length);
|
|
||||||
RealName = RealName.substr(Length);
|
|
||||||
|
|
||||||
// Because ValueRequired is an invalid flag for grouped arguments,
|
|
||||||
// we don't need to pass argc/argv in.
|
|
||||||
//
|
|
||||||
assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&
|
|
||||||
"Option can not be cl::Grouping AND cl::ValueRequired!");
|
|
||||||
int Dummy;
|
|
||||||
ErrorParsing |= ProvideOption(PGOpt, RealArgName,
|
|
||||||
StringRef(), 0, 0, Dummy);
|
|
||||||
|
|
||||||
// Get the next grouping option.
|
|
||||||
PGOpt = getOptionPred(RealName, Length, isGrouping, Opts);
|
|
||||||
} while (PGOpt && Length != RealName.size());
|
|
||||||
|
|
||||||
Handler = PGOpt; // Ate all of the options.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Handler == 0) {
|
if (Handler == 0) {
|
||||||
@ -650,7 +668,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
|
|||||||
ErrorParsing = true;
|
ErrorParsing = true;
|
||||||
|
|
||||||
} else if (ConsumeAfterOpt == 0) {
|
} else if (ConsumeAfterOpt == 0) {
|
||||||
// Positional args have already been handled if ConsumeAfter is specified...
|
// Positional args have already been handled if ConsumeAfter is specified.
|
||||||
unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
|
unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
|
||||||
for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
|
for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
|
||||||
if (RequiresValue(PositionalOpts[i])) {
|
if (RequiresValue(PositionalOpts[i])) {
|
||||||
@ -807,8 +825,8 @@ size_t alias::getOptionWidth() const {
|
|||||||
// Print out the option for the alias.
|
// Print out the option for the alias.
|
||||||
void alias::printOptionInfo(size_t GlobalWidth) const {
|
void alias::printOptionInfo(size_t GlobalWidth) const {
|
||||||
size_t L = std::strlen(ArgStr);
|
size_t L = std::strlen(ArgStr);
|
||||||
errs() << " -" << ArgStr << std::string(GlobalWidth-L-6, ' ') << " - "
|
errs() << " -" << ArgStr;
|
||||||
<< HelpStr << "\n";
|
errs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -967,21 +985,21 @@ void generic_parser_base::printOptionInfo(const Option &O,
|
|||||||
size_t GlobalWidth) const {
|
size_t GlobalWidth) const {
|
||||||
if (O.hasArgStr()) {
|
if (O.hasArgStr()) {
|
||||||
size_t L = std::strlen(O.ArgStr);
|
size_t L = std::strlen(O.ArgStr);
|
||||||
outs() << " -" << O.ArgStr << std::string(GlobalWidth-L-6, ' ')
|
outs() << " -" << O.ArgStr;
|
||||||
<< " - " << O.HelpStr << '\n';
|
outs().indent(GlobalWidth-L-6) << " - " << O.HelpStr << '\n';
|
||||||
|
|
||||||
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
|
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
|
||||||
size_t NumSpaces = GlobalWidth-strlen(getOption(i))-8;
|
size_t NumSpaces = GlobalWidth-strlen(getOption(i))-8;
|
||||||
outs() << " =" << getOption(i) << std::string(NumSpaces, ' ')
|
outs() << " =" << getOption(i);
|
||||||
<< " - " << getDescription(i) << '\n';
|
outs().indent(NumSpaces) << " - " << getDescription(i) << '\n';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (O.HelpStr[0])
|
if (O.HelpStr[0])
|
||||||
outs() << " " << O.HelpStr << "\n";
|
outs() << " " << O.HelpStr << '\n';
|
||||||
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
|
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
|
||||||
size_t L = std::strlen(getOption(i));
|
size_t L = std::strlen(getOption(i));
|
||||||
outs() << " -" << getOption(i) << std::string(GlobalWidth-L-8, ' ')
|
outs() << " -" << getOption(i);
|
||||||
<< " - " << getDescription(i) << "\n";
|
outs().indent(GlobalWidth-L-8) << " - " << getDescription(i) << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1121,7 +1139,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
outs() << ".\n"
|
outs() << ".\n"
|
||||||
<< " Built " << __DATE__ << " (" << __TIME__ << ").\n"
|
<< " Built " << __DATE__ << " (" << __TIME__ << ").\n"
|
||||||
<< " Host: " << sys::getHostTriple() << "\n"
|
<< " Host: " << sys::getHostTriple() << '\n'
|
||||||
<< "\n"
|
<< "\n"
|
||||||
<< " Registered Targets:\n";
|
<< " Registered Targets:\n";
|
||||||
|
|
||||||
@ -1135,9 +1153,9 @@ public:
|
|||||||
std::sort(Targets.begin(), Targets.end());
|
std::sort(Targets.begin(), Targets.end());
|
||||||
|
|
||||||
for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Targets.size(); i != e; ++i) {
|
||||||
outs() << " " << Targets[i].first
|
outs() << " " << Targets[i].first;
|
||||||
<< std::string(Width - Targets[i].first.length(), ' ') << " - "
|
outs().indent(Width - Targets[i].first.length()) << " - "
|
||||||
<< Targets[i].second->getShortDescription() << "\n";
|
<< Targets[i].second->getShortDescription() << '\n';
|
||||||
}
|
}
|
||||||
if (Targets.empty())
|
if (Targets.empty())
|
||||||
outs() << " (none)\n";
|
outs() << " (none)\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user