[PATCH] Extra Command Line library functionality (option grouping and runtime inspection/modification)
Tobias Grosser
tobias at grosser.es
Mon Apr 15 10:07:21 PDT 2013
On 04/09/2013 01:09 PM, Daniel Liew wrote:
> I realised my naming of the default option category wasn't such a good
> idea (a category called "Default" is confusing) so I've amended my
> first patch so that the default category is called "General".
>
> The amended patch (001-amended.patch) is attached. I should also note
> that patch 001 needs to be applied before patch 002.
I like the general idea. I have no idea about the design of the option
class, but gere some style comments:
> ---
> include/llvm/Support/CommandLine.h | 50 ++++++++++--
> lib/Support/CommandLine.cpp | 150 +++++++++++++++++++++++++++++++++---
> 2 files changed, 185 insertions(+), 15 deletions(-)
>
> diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
> index 2e84d7b..6331096 100644
> --- a/include/llvm/Support/CommandLine.h
> +++ b/include/llvm/Support/CommandLine.h
> @@ -137,7 +137,24 @@ enum MiscFlags { // Miscellaneous flags to adjust argument
> Sink = 0x04 // Should this cl::list eat all unknown options?
> };
>
> +//===----------------------------------------------------------------------===//
> +// Option Category class
> +//
> +class OptionCategory {
> +private:
> + const char* name;
> + const char* description;
Variables start with uppercase letters.
> +public:
> + OptionCategory(const char* _name, const char* _description=0) {
Variables start with uppercase letters.
No need for the underscore here. Just initialize the values in the
initializer list.
> + name=_name;
> + description=_description;
> + }
> + const char* getName() { return name;}
^ Space
> + const char* getDescription() { return description;}
> +};
>
> +//The general Option Category (used as default category)
^ Space
> +extern OptionCategory generalCategory;
>
> //===----------------------------------------------------------------------===//
> // Option Base class
> @@ -160,6 +177,9 @@ class Option {
> // Out of line virtual function to provide home for the class.
> virtual void anchor();
>
> + //Register Option Category
Space between // and the first word.
> + void registerCategory();
> +
> int NumOccurrences; // The number of times specified
> + OptionCategory* category; //The Category this option belongs to
Start the variable name with an uppercase letter.
> +// cat - Specifiy the Option category for the command line argument to belong
> +// to
This seems to be an old doxygen style comment. We now do not repeat the
structure name but just start with the comment.
> +
> +struct cat {
> + OptionCategory& category;
> + cat(OptionCategory& c) : category(c) {}
I am unsure about the position of the '&' sign. Can you verify what the
style is in LLVM. (In general you can use clang-format to check your code.
> +
> + template<class Opt>
> + void apply(Opt &O) const { O.setCategory(category); }
Start with uppercase.
> diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
> index 560d7eb..c191f9c 100644
> --- a/lib/Support/CommandLine.cpp
> +++ b/lib/Support/CommandLine.cpp
> @@ -31,6 +31,7 @@
> #include "llvm/Support/Path.h"
> #include "llvm/Support/raw_ostream.h"
> #include "llvm/Support/system_error.h"
> +#include <map>
> #include <cerrno>
> #include <cstdlib>
Please sort alphabetically. Also, are you sure you want to use a map and
not one of the LLVM specific ADTs?
> using namespace llvm;
> @@ -106,6 +107,17 @@ void Option::addArgument() {
> MarkOptionsChanged();
> }
>
> +// This collects the different option categories that have been registered
Missing point at the end.
> +typedef SmallPtrSet<OptionCategory*,16> OptionCatSet;
> +static ManagedStatic<OptionCatSet> registeredOptionCategories;
> +
> +//Initialise the general option category
^ Missing space.
> +OptionCategory llvm::cl::generalCategory("General options");
> +
> +
> +void Option::registerCategory() {
> + registeredOptionCategories->insert(this->category);
Why do you need 'this->' here?
> +}
>
> //===----------------------------------------------------------------------===//
> // Basic, shared command line option processing machinery.
> @@ -1227,6 +1239,15 @@ class HelpPrinter {
> public:
> explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
>
> + typedef SmallVector<std::pair<const char *, Option*>,128> StrOptionPairVector;
> +
> + virtual void printOptions(
> + StrOptionPairVector& Opts, size_t MaxArgLen)
> + {
> + for (size_t i = 0, e = Opts.size(); i != e; ++i)
> + Opts[i].second->printOptionInfo(MaxArgLen);
> + }
> +
> void operator=(bool Value) {
> if (Value == false) return;
>
> @@ -1236,7 +1257,7 @@ public:
> StringMap<Option*> OptMap;
> GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
>
> - SmallVector<std::pair<const char *, Option*>, 128> Opts;
> + StrOptionPairVector Opts;
> sortOpts(OptMap, Opts, ShowHidden);
>
> if (ProgramOverview)
> @@ -1267,8 +1288,7 @@ public:
> MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
>
> outs() << "OPTIONS:\n";
> - for (size_t i = 0, e = Opts.size(); i != e; ++i)
> - Opts[i].second->printOptionInfo(MaxArgLen);
> + printOptions(Opts,MaxArgLen);
^ Space
>
> // Print any extra help the user has declared.
> for (std::vector<const char *>::iterator I = MoreHelp->begin(),
> @@ -1280,6 +1300,88 @@ public:
> exit(1);
> }
> };
> +
> +class CategorizedHelpPrinter : public HelpPrinter
> +{
> +public:
> + explicit CategorizedHelpPrinter(bool showHidden) : HelpPrinter(showHidden) {}
> +
> + //Helper function for printOptions()
> + //It shall return true if "a" should be ordered before "b", false otherwise
^ Space
> + static bool OptionCategoryCompare(OptionCategory* a,OptionCategory* b) {
OptionCategory *A
> + assert(strcmp(a->getName(),b->getName()) !=0 &&
> + //Make sure we inherit our base class's operator=()
Space after //
> + using HelpPrinter::operator=;
> +
> + virtual void printOptions(
> + StrOptionPairVector& Opts, size_t MaxArgLen)
> + {
> + std::vector<OptionCategory*> sortedCategories;
> + std::map<OptionCategory*,std::vector<Option*> > categorizedOptions;
> +
> + //Find the different option groups and sort them alphabetically
> + for (OptionCatSet::const_iterator
> + i= registeredOptionCategories->begin(),
Use I as an uppercase letter.
> + E= registeredOptionCategories->end();
> + i != E; ++i)
> + {
This should be on the same line as the )
> + sortedCategories.push_back(*i);
> + }
> + assert(sortedCategories.size() > 0 && "No option categories registered!");
> + std::sort(sortedCategories.begin(),
> + sortedCategories.end(),
> + OptionCategoryCompare);
Does this fit in fewer lines?
> // Define the two HelpPrinter instances that are used to print out help, or
> @@ -1288,6 +1390,12 @@ public:
> static HelpPrinter NormalPrinter(false);
> static HelpPrinter HiddenPrinter(true);
>
> +// Define the two CategorizedHelpPrinter instances that are used to
> +// print out help-cat or help-cat-hidden with the
> +// options displayed in categories
Missing '.' at the end of the sentence. Also, please fill the 80 column
limit.
I stopped here, but I hope this gives you an idea of some of the style
problems that need to be fixed.
Tobias
More information about the llvm-commits
mailing list