#ifndef LLVM_SUPPORT_COMMANDLINE_H
#define LLVM_SUPPORT_COMMANDLINE_H
-#include "llvm/Support/type_traits.h"
-#include "llvm/Support/Compiler.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/type_traits.h"
#include <cassert>
#include <climits>
#include <cstdarg>
//===----------------------------------------------------------------------===//
// ParseCommandLineOptions - Command line option processing entry point.
//
-void ParseCommandLineOptions(int argc, char **argv,
- const char *Overview = 0,
- bool ReadResponseFiles = false);
+void ParseCommandLineOptions(int argc, const char * const *argv,
+ const char *Overview = 0);
//===----------------------------------------------------------------------===//
// ParseEnvironmentOptions - Environment variable option processing alternate
// entry point.
//
void ParseEnvironmentOptions(const char *progName, const char *envvar,
- const char *Overview = 0,
- bool ReadResponseFiles = false);
+ const char *Overview = 0);
///===---------------------------------------------------------------------===//
/// SetVersionPrinter - Override the default (LLVM specific) version printer
Sink = 0x04 // Should this cl::list eat all unknown options?
};
+//===----------------------------------------------------------------------===//
+// Option Category class
+//
+class OptionCategory {
+private:
+ const char *const Name;
+ const char *const Description;
+ void registerCategory();
+public:
+ OptionCategory(const char *const Name, const char *const Description = 0)
+ : Name(Name), Description(Description) { registerCategory(); }
+ const char *getName() const { return Name; }
+ const char *getDescription() const { return Description; }
+};
+// The general Option Category (used as default category).
+extern OptionCategory GeneralCategory;
//===----------------------------------------------------------------------===//
// Option Base class
unsigned Position; // Position of last occurrence of the option
unsigned AdditionalVals;// Greater than 0 for multi-valued option.
Option *NextRegistered; // Singly linked list of registered options.
+
public:
- const char *ArgStr; // The argument string itself (ex: "help", "o")
- const char *HelpStr; // The descriptive text message for -help
- const char *ValueStr; // String describing what the value of this option is
+ const char *ArgStr; // The argument string itself (ex: "help", "o")
+ const char *HelpStr; // The descriptive text message for -help
+ const char *ValueStr; // String describing what the value of this option is
+ OptionCategory *Category; // The Category this option belongs to
inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
return (enum NumOccurrencesFlag)Occurrences;
void setFormattingFlag(enum FormattingFlags V) { Formatting = V; }
void setMiscFlag(enum MiscFlags M) { Misc |= M; }
void setPosition(unsigned pos) { Position = pos; }
+ void setCategory(OptionCategory &C) { Category = &C; }
protected:
- explicit Option(enum NumOccurrencesFlag Occurrences,
+ explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
enum OptionHidden Hidden)
- : NumOccurrences(0), Occurrences(Occurrences), HiddenFlag(Hidden),
- Formatting(NormalFormatting), Position(0),
- AdditionalVals(0), NextRegistered(0),
- ArgStr(""), HelpStr(""), ValueStr("") {
+ : NumOccurrences(0), Occurrences(OccurrencesFlag), Value(0),
+ HiddenFlag(Hidden), Formatting(NormalFormatting), Misc(0),
+ Position(0), AdditionalVals(0), NextRegistered(0),
+ ArgStr(""), HelpStr(""), ValueStr(""), Category(&GeneralCategory) {
}
inline void setNumAdditionalVals(unsigned n) { AdditionalVals = n; }
//
void addArgument();
+ /// Unregisters this option from the CommandLine system.
+ ///
+ /// This option must have been the last option registered.
+ /// For testing purposes only.
+ void removeArgument();
+
Option *getNextRegisteredOption() const { return NextRegistered; }
// Return the width of the option tag for printing...
template<class Ty>
LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
+// cat - Specifiy the Option category for the command line argument to belong
+// to.
+struct cat {
+ OptionCategory &Category;
+ cat(OptionCategory &c) : Category(c) {}
+
+ template<class Opt>
+ void apply(Opt &O) const { O.setCategory(Category); }
+};
+
//===----------------------------------------------------------------------===//
// OptionValue class
struct GenericOptionValue {
virtual ~GenericOptionValue() {}
virtual bool compare(const GenericOptionValue &V) const = 0;
+
private:
virtual void anchor();
};
bool hasValue() const { return false; }
- const DataType &getValue() const { assert(false && "no default value"); }
+ const DataType &getValue() const { llvm_unreachable("no default value"); }
// Some options may take their value from a different data type.
template<class DT>
bool compare(const DataType &/*V*/) const { return false; }
- virtual bool compare(const GenericOptionValue& /*V*/) const { return false; }
+ bool compare(const GenericOptionValue& /*V*/) const override {
+ return false;
+ }
};
// Simple copy of the option value.
return Valid && (Value != V);
}
- virtual bool compare(const GenericOptionValue &V) const {
+ bool compare(const GenericOptionValue &V) const override {
const OptionValueCopy<DataType> &VC =
static_cast< const OptionValueCopy<DataType>& >(V);
if (!VC.hasValue()) return false;
return *this;
}
private:
- virtual void anchor();
+ void anchor() override;
};
template<>
return *this;
}
private:
- virtual void anchor();
+ void anchor() override;
};
//===----------------------------------------------------------------------===//
template<class Opt>
void apply(Opt &O) const {
- for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
- i != e; ++i)
+ for (size_t i = 0, e = Values.size(); i != e; ++i)
O.getParser().addLiteralOption(Values[i].first, Values[i].second.first,
Values[i].second.second);
}
typedef DataType parser_data_type;
// Implement virtual functions needed by generic_parser_base
- unsigned getNumOptions() const { return unsigned(Values.size()); }
- const char *getOption(unsigned N) const { return Values[N].Name; }
- const char *getDescription(unsigned N) const {
+ unsigned getNumOptions() const override { return unsigned(Values.size()); }
+ const char *getOption(unsigned N) const override { return Values[N].Name; }
+ const char *getDescription(unsigned N) const override {
return Values[N].HelpStr;
}
// getOptionValue - Return the value of option name N.
- virtual const GenericOptionValue &getOptionValue(unsigned N) const {
+ const GenericOptionValue &getOptionValue(unsigned N) const override {
return Values[N].V;
}
else
ArgVal = ArgName;
- for (unsigned i = 0, e = static_cast<unsigned>(Values.size());
- i != e; ++i)
+ for (size_t i = 0, e = Values.size(); i != e; ++i)
if (Values[i].Name == ArgVal) {
V = Values[i].V.getValue();
return false;
}
// getValueName - Do not print =<value> at all.
- virtual const char *getValueName() const { return 0; }
+ const char *getValueName() const override { return 0; }
void printOptionDiff(const Option &O, bool V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
}
// getValueName - Do not print =<value> at all.
- virtual const char *getValueName() const { return 0; }
+ const char *getValueName() const override { return 0; }
void printOptionDiff(const Option &O, boolOrDefault V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
bool parse(Option &O, StringRef ArgName, StringRef Arg, int &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "int"; }
+ const char *getValueName() const override { return "int"; }
void printOptionDiff(const Option &O, int V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<int>);
bool parse(Option &O, StringRef ArgName, StringRef Arg, unsigned &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "uint"; }
+ const char *getValueName() const override { return "uint"; }
void printOptionDiff(const Option &O, unsigned V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
unsigned long long &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "uint"; }
+ const char *getValueName() const override { return "uint"; }
void printOptionDiff(const Option &O, unsigned long long V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<unsigned long long>);
bool parse(Option &O, StringRef ArgName, StringRef Arg, double &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "number"; }
+ const char *getValueName() const override { return "number"; }
void printOptionDiff(const Option &O, double V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<double>);
bool parse(Option &O, StringRef ArgName, StringRef Arg, float &Val);
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "number"; }
+ const char *getValueName() const override { return "number"; }
void printOptionDiff(const Option &O, float V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<float>);
}
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "string"; }
+ const char *getValueName() const override { return "string"; }
void printOptionDiff(const Option &O, StringRef V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<std::string>);
}
// getValueName - Overload in subclass to provide a better default value.
- virtual const char *getValueName() const { return "char"; }
+ const char *getValueName() const override { return "char"; }
void printOptionDiff(const Option &O, char V, OptVal Default,
size_t GlobalWidth) const;
// An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
+ void anchor() override;
};
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<char>);
};
template<> struct applicator<NumOccurrencesFlag> {
- static void opt(NumOccurrencesFlag NO, Option &O) {
- O.setNumOccurrencesFlag(NO);
+ static void opt(NumOccurrencesFlag N, Option &O) {
+ O.setNumOccurrencesFlag(N);
}
};
template<> struct applicator<ValueExpected> {
DataType *Location; // Where to store the object...
OptionValue<DataType> Default;
- void check() const {
+ void check_location() const {
assert(Location != 0 && "cl::location(...) not specified for a command "
"line option with external storage, "
"or cl::init specified before cl::location()!!");
template<class T>
void setValue(const T &V, bool initial = false) {
- check();
+ check_location();
*Location = V;
if (initial)
Default = V;
}
- DataType &getValue() { check(); return *Location; }
- const DataType &getValue() const { check(); return *Location; }
+ DataType &getValue() { check_location(); return *Location; }
+ const DataType &getValue() const { check_location(); return *Location; }
operator DataType() const { return this->getValue(); }
// Make sure we initialize the value with the default constructor for the
// type.
- opt_storage() : Value(DataType()) {}
+ opt_storage() : Value(DataType()), Default(DataType()) {}
template<class T>
void setValue(const T &V, bool initial = false) {
is_class<DataType>::value> {
ParserClass Parser;
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName,
- StringRef Arg) {
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
return false;
}
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
- virtual void printOptionValue(size_t GlobalWidth, bool Force) const {
+ void printOptionValue(size_t GlobalWidth, bool Force) const override {
if (Force || this->getDefault().compare(this->getValue())) {
cl::printOptionDiff<ParserClass>(
*this, Parser, this->getValue(), this->getDefault(), GlobalWidth);
std::vector<unsigned> Positions;
ParserClass Parser;
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
// Unimplemented: list options don't currently store their default value.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
void done() {
addArgument();
std::vector<unsigned> Positions;
ParserClass Parser;
- virtual enum ValueExpected getValueExpectedFlagDefault() const {
+ enum ValueExpected getValueExpectedFlagDefault() const override {
return Parser.getValueExpectedFlagDefault();
}
- virtual void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) {
+ void getExtraOptionNames(SmallVectorImpl<const char*> &OptionNames) override {
return Parser.getExtraOptionNames(OptionNames);
}
- virtual bool handleOccurrence(unsigned pos, StringRef ArgName, StringRef Arg){
+ bool handleOccurrence(unsigned pos, StringRef ArgName,
+ StringRef Arg) override {
typename ParserClass::parser_data_type Val =
typename ParserClass::parser_data_type();
if (Parser.parse(*this, ArgName, Arg, Val))
return true; // Parse Error!
- addValue(Val);
+ this->addValue(Val);
setPosition(pos);
Positions.push_back(pos);
return false;
}
// Forward printing stuff to the parser...
- virtual size_t getOptionWidth() const {return Parser.getOptionWidth(*this);}
- virtual void printOptionInfo(size_t GlobalWidth) const {
+ size_t getOptionWidth() const override {return Parser.getOptionWidth(*this);}
+ void printOptionInfo(size_t GlobalWidth) const override {
Parser.printOptionInfo(*this, GlobalWidth);
}
// Unimplemented: bits options don't currently store their default values.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
void done() {
addArgument();
class alias : public Option {
Option *AliasFor;
- virtual bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
- StringRef Arg) {
+ bool handleOccurrence(unsigned pos, StringRef /*ArgName*/,
+ StringRef Arg) override {
return AliasFor->handleOccurrence(pos, AliasFor->ArgStr, Arg);
}
// Handle printing stuff...
- virtual size_t getOptionWidth() const;
- virtual void printOptionInfo(size_t GlobalWidth) const;
+ size_t getOptionWidth() const override;
+ void printOptionInfo(size_t GlobalWidth) const override;
// Aliases do not need to print their values.
- virtual void printOptionValue(size_t /*GlobalWidth*/, bool /*Force*/) const {}
+ void printOptionValue(size_t /*GlobalWidth*/,
+ bool /*Force*/) const override {}
+
+ ValueExpected getValueExpectedFlagDefault() const override {
+ return AliasFor->getValueExpectedFlag();
+ }
void done() {
if (!hasArgStr())
};
void PrintVersionMessage();
-// This function just prints the help message, exactly the same way as if the
-// -help option had been given on the command line.
-// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
-void PrintHelpMessage();
+
+/// This function just prints the help message, exactly the same way as if the
+/// -help or -help-hidden option had been given on the command line.
+///
+/// NOTE: THIS FUNCTION TERMINATES THE PROGRAM!
+///
+/// \param Hidden if true will print hidden options
+/// \param Categorized if true print options in categories
+void PrintHelpMessage(bool Hidden=false, bool Categorized=false);
+
+
+//===----------------------------------------------------------------------===//
+// Public interface for accessing registered options.
+//
+
+/// \brief Use this to get a StringMap to all registered named options
+/// (e.g. -help). Note \p Map Should be an empty StringMap.
+///
+/// \param [out] Map will be filled with mappings where the key is the
+/// Option argument string (e.g. "help") and value is the corresponding
+/// Option*.
+///
+/// Access to unnamed arguments (i.e. positional) are not provided because
+/// it is expected that the client already has access to these.
+///
+/// Typical usage:
+/// \code
+/// main(int argc,char* argv[]) {
+/// StringMap<llvm::cl::Option*> opts;
+/// llvm::cl::getRegisteredOptions(opts);
+/// assert(opts.count("help") == 1)
+/// opts["help"]->setDescription("Show alphabetical help information")
+/// // More code
+/// llvm::cl::ParseCommandLineOptions(argc,argv);
+/// //More code
+/// }
+/// \endcode
+///
+/// This interface is useful for modifying options in libraries that are out of
+/// the control of the client. The options should be modified before calling
+/// llvm::cl::ParseCommandLineOptions().
+void getRegisteredOptions(StringMap<Option*> &Map);
+
+//===----------------------------------------------------------------------===//
+// Standalone command line processing utilities.
+//
+
+/// \brief Saves strings in the inheritor's stable storage and returns a stable
+/// raw character pointer.
+class StringSaver {
+ virtual void anchor();
+public:
+ virtual const char *SaveString(const char *Str) = 0;
+ virtual ~StringSaver() {}; // Pacify -Wnon-virtual-dtor.
+};
+
+/// \brief Tokenizes a command line that can contain escapes and quotes.
+//
+/// The quoting rules match those used by GCC and other tools that use
+/// libiberty's buildargv() or expandargv() utilities, and do not match bash.
+/// They differ from buildargv() on treatment of backslashes that do not escape
+/// a special character to make it possible to accept most Windows file paths.
+///
+/// \param [in] Source The string to be split on whitespace with quotes.
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [out] NewArgv All parsed strings are appended to NewArgv.
+void TokenizeGNUCommandLine(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief Tokenizes a Windows command line which may contain quotes and escaped
+/// quotes.
+///
+/// See MSDN docs for CommandLineToArgvW for information on the quoting rules.
+/// http://msdn.microsoft.com/en-us/library/windows/desktop/17w5ykft(v=vs.85).aspx
+///
+/// \param [in] Source The string to be split on whitespace with quotes.
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [out] NewArgv All parsed strings are appended to NewArgv.
+void TokenizeWindowsCommandLine(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief String tokenization function type. Should be compatible with either
+/// Windows or Unix command line tokenizers.
+typedef void (*TokenizerCallback)(StringRef Source, StringSaver &Saver,
+ SmallVectorImpl<const char *> &NewArgv);
+
+/// \brief Expand response files on a command line recursively using the given
+/// StringSaver and tokenization strategy. Argv should contain the command line
+/// before expansion and will be modified in place.
+///
+/// \param [in] Saver Delegates back to the caller for saving parsed strings.
+/// \param [in] Tokenizer Tokenization strategy. Typically Unix or Windows.
+/// \param [in,out] Argv Command line into which to expand response files.
+/// \return true if all @files were expanded successfully or there were none.
+bool ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
+ SmallVectorImpl<const char *> &Argv);
} // End namespace cl