+// RemoveArgument - It's possible that the argument is no longer in the map if
+// options have already been processed and the map has been deleted!
+//
+static void RemoveArgument(const char *ArgName, Option *Opt) {
+ if (Options->empty()) return;
+
+#ifndef NDEBUG
+ // This disgusting HACK is brought to you courtesy of GCC 3.3.2, which ICE's
+ // If we pass ArgName directly into getOption here.
+ std::string Tmp = ArgName;
+ assert(getOption(Tmp) == Opt && "Arg not in map!");
+#endif
+ Options->erase(ArgName);
+}
+
+static inline bool ProvideOption(Option *Handler, const char *ArgName,
+ const char *Value, int argc, char **argv,
+ int &i) {
+ // Enforce value requirements
+ switch (Handler->getValueExpectedFlag()) {
+ case ValueRequired:
+ if (Value == 0) { // No value specified?
+ if (i+1 < argc) { // Steal the next argument, like for '-o filename'
+ Value = argv[++i];
+ } else {
+ return Handler->error(" requires a value!");
+ }
+ }
+ break;
+ case ValueDisallowed:
+ if (Value)
+ return Handler->error(" does not allow a value! '" +
+ std::string(Value) + "' specified.");
+ break;
+ case ValueOptional:
+ break;
+ default:
+ cerr << ProgramName
+ << ": Bad ValueMask flag! CommandLine usage error:"
+ << Handler->getValueExpectedFlag() << "\n";
+ abort();
+ break;
+ }
+
+ // Run the handler now!
+ return Handler->addOccurrence(i, ArgName, Value ? Value : "");
+}
+
+static bool ProvidePositionalOption(Option *Handler, const std::string &Arg,
+ int i) {
+ int Dummy = i;
+ return ProvideOption(Handler, Handler->ArgStr, Arg.c_str(), 0, 0, Dummy);
+}
+
+
+// Option predicates...
+static inline bool isGrouping(const Option *O) {
+ return O->getFormattingFlag() == cl::Grouping;
+}
+static inline bool isPrefixedOrGrouping(const Option *O) {
+ return isGrouping(O) || O->getFormattingFlag() == cl::Prefix;
+}
+
+// getOptionPred - Check to see if there are any options that satisfy the
+// specified predicate with names that are the prefixes in Name. This is
+// checked by progressively stripping characters off of the name, checking to
+// see if there options that satisfy the predicate. If we find one, return it,
+// otherwise return null.
+//
+static Option *getOptionPred(std::string Name, unsigned &Length,
+ bool (*Pred)(const Option*)) {
+
+ Option *Op = getOption(Name);
+ if (Op && Pred(Op)) {
+ Length = Name.length();
+ return Op;
+ }
+
+ if (Name.size() == 1) return 0;
+ do {
+ Name.erase(Name.end()-1, Name.end()); // Chop off the last character...
+ Op = getOption(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 ((Op == 0 || !Pred(Op)) && Name.size() > 1);
+
+ if (Op && Pred(Op)) {
+ Length = Name.length();
+ return Op; // Found one!
+ }
+ return 0; // No option found!
+}
+
+static bool RequiresValue(const Option *O) {
+ return O->getNumOccurrencesFlag() == cl::Required ||
+ O->getNumOccurrencesFlag() == cl::OneOrMore;
+}
+
+static bool EatsUnboundedNumberOfValues(const Option *O) {
+ return O->getNumOccurrencesFlag() == cl::ZeroOrMore ||
+ O->getNumOccurrencesFlag() == cl::OneOrMore;
+}
+
+/// ParseCStringVector - Break INPUT up wherever one or more
+/// whitespace characters are found, and store the resulting tokens in
+/// OUTPUT. The tokens stored in OUTPUT are dynamically allocated
+/// using strdup (), so it is the caller's responsibility to free ()
+/// them later.
+///
+static void ParseCStringVector(std::vector<char *> &output,
+ const char *input) {
+ // Characters which will be treated as token separators:
+ static const char *delims = " \v\f\t\r\n";
+
+ std::string work (input);
+ // Skip past any delims at head of input string.
+ size_t pos = work.find_first_not_of (delims);
+ // If the string consists entirely of delims, then exit early.
+ if (pos == std::string::npos) return;
+ // Otherwise, jump forward to beginning of first word.
+ work = work.substr (pos);
+ // Find position of first delimiter.
+ pos = work.find_first_of (delims);
+
+ while (!work.empty() && pos != std::string::npos) {
+ // Everything from 0 to POS is the next word to copy.
+ output.push_back (strdup (work.substr (0,pos).c_str ()));
+ // Is there another word in the string?
+ size_t nextpos = work.find_first_not_of (delims, pos + 1);
+ if (nextpos != std::string::npos) {
+ // Yes? Then remove delims from beginning ...
+ work = work.substr (work.find_first_not_of (delims, pos + 1));
+ // and find the end of the word.
+ pos = work.find_first_of (delims);
+ } else {
+ // No? (Remainder of string is delims.) End the loop.
+ work = "";
+ pos = std::string::npos;
+ }
+ }
+
+ // If `input' ended with non-delim char, then we'll get here with
+ // the last word of `input' in `work'; copy it now.
+ if (!work.empty ()) {
+ output.push_back (strdup (work.c_str ()));
+ }
+}
+
+/// ParseEnvironmentOptions - An alternative entry point to the
+/// CommandLine library, which allows you to read the program's name
+/// from the caller (as PROGNAME) and its command-line arguments from
+/// an environment variable (whose name is given in ENVVAR).
+///
+void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
+ const char *Overview) {
+ // Check args.
+ assert(progName && "Program name not specified");
+ assert(envVar && "Environment variable name missing");
+
+ // Get the environment variable they want us to parse options out of.
+ const char *envValue = getenv(envVar);
+ if (!envValue)
+ return;
+
+ // Get program's "name", which we wouldn't know without the caller
+ // telling us.
+ std::vector<char*> newArgv;
+ newArgv.push_back(strdup(progName));
+
+ // Parse the value of the environment variable into a "command line"
+ // and hand it off to ParseCommandLineOptions().
+ ParseCStringVector(newArgv, envValue);
+ int newArgc = newArgv.size();
+ ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
+
+ // Free all the strdup()ed strings.
+ for (std::vector<char*>::iterator i = newArgv.begin(), e = newArgv.end();
+ i != e; ++i)
+ free (*i);
+}
+
+/// LookupOption - Lookup the option specified by the specified option on the
+/// command line. If there is a value specified (after an equal sign) return
+/// that as well.
+static Option *LookupOption(const char *&Arg, const char *&Value) {
+ while (*Arg == '-') ++Arg; // Eat leading dashes
+
+ const char *ArgEnd = Arg;
+ while (*ArgEnd && *ArgEnd != '=')
+ ++ArgEnd; // Scan till end of argument name.
+
+ if (*ArgEnd == '=') // If we have an equals sign...
+ Value = ArgEnd+1; // Get the value, not the equals
+
+
+ if (*Arg == 0) return 0;
+
+ // Look up the option.
+ std::map<std::string, Option*> &Opts = *Options;
+ std::map<std::string, Option*>::iterator I =
+ Opts.find(std::string(Arg, ArgEnd));
+ return (I != Opts.end()) ? I->second : 0;
+}