getopt_doc.h

Go to the documentation of this file.
00001 /* Copyright Benoit Hudson 2008 */
00002 #ifndef getopt_doc_HEADER
00003 #define getopt_doc_HEADER
00004 
00005 #ifdef HAVE_CONFIG_H
00006  #include <config.h>
00007 #endif
00008 
00009 /***************************************************************************
00010  * A version of getopt that is less soul-sucking.
00011  *
00012  * Most important, it allows documenting the options.
00013  *
00014  * Usage:
00015  *
00016  * int main (int argc, char **argv) {
00017  *   OptionSet opts;
00018  *   bool bar = false;
00019  *   std::string cow = "Bessie";
00020  *   int bottles = 99;
00021  *   float cash = 0.0;
00022  *
00023  *   opts.addFlag("bar", true, "include bar", &bar);
00024  *   opts.addOption("cowname", "name", "name the cow", &cow);
00025  *   opts.addIntOption("bottles", "num", "number of bottles of beer on the wall", &bottles);
00026  *   opts.addFloatOption("cash", "$$.cc", "amount of cash in the register", &cash);
00027  *   opts.addSynonym("cowname", "c");
00028  *
00029  *   CommandLine cmds (opts, argc, argv);
00030  *   if (!cmds.process()) cmds.printUsage(1, "Says something silly.");
00031  *   printf("%s is %s counting the %d bottles on the wall.\n"
00032  *      , cow.c_str(), bar ? "at the bar" : "on a stool", bottles);
00033  * }
00034  *
00035  * ./a.out -c Marguerite --cash=50.23 --bottles=10 --bar=no
00036  * Marguerite is counting the 10 bottles on the wall.
00037  ***************************************************************************/
00038 
00039 #include <string>
00040 #include <vector>
00041 
00042 namespace hudson {
00043   struct CommandLine;
00044 
00045   struct OptionSet {
00046     OptionSet();
00047     ~OptionSet();
00048 
00049     /* Add a flag with no arguments, like "-f" or "--flag". */
00050 
00051     void addFlag(
00052         const std::string& name,
00053         const std::string& description,
00054         bool *output);
00055 
00056     /* Add a flag with a string argument, like "--string=foo". */
00057     void addOption(
00058         const std::string& name,
00059         const std::string& variable_description,
00060         const std::string& description,
00061         std::string *output);
00062 
00063     /* Add a flag with an int argument, like "--answer=42". */
00064     void addIntOption(
00065         const std::string& name,
00066         const std::string& variable_description,
00067         const std::string& description,
00068         int *output);
00069 
00070     /* Add a flag with a floating-point argument, like "--delta=0.6". */
00071     void addFloatOption(
00072         const std::string& name,
00073         const std::string& variable_description,
00074         const std::string& description,
00075         double *output
00076         );
00077 
00078     /* Add a flag as a synonym for a previously-declared flag. */
00079     void addSynonym(
00080         const std::string& canonical,
00081         const std::string& alternate);
00082 
00083     /* Add a non-flag; just a spacer in the documentation.  
00084      * Don't include the newline; that's done here. */
00085     void addSpacer(const std::string& message);
00086 
00087     void print();
00088 
00089     private:
00090     friend struct CommandLine;
00091     struct guts;
00092     guts *guts_;
00093   };
00094 
00095   struct CommandLine {
00096     typedef std::vector<std::string> Arguments;
00097 
00098     CommandLine(const OptionSet&, int argc, const char * const *argv);
00099     CommandLine(const OptionSet&, const Arguments&);
00100     const Arguments& getArguments() const { return args; }
00101 
00102     bool hasNext() { return !done; }
00103     bool readNext();
00104     bool process() {
00105       bool ok = true;
00106       while(hasNext()) {
00107         bool success = readNext(); // always call readNext
00108         ok = success && ok; // don't merge these two lines
00109       }
00110       return ok;
00111     }
00112 
00113     unsigned index() { return current_index; }
00114 
00115     void printUsageAndExit(int exitval, const std::string& arguments,
00116         const std::string& description);
00117 
00118     private:
00119     void checkNext();
00120     bool interpret(const std::string& option);
00121 
00122     Arguments args;
00123     const OptionSet& opts;
00124     unsigned current_index;
00125     bool done;
00126   };
00127 };
00128 
00129 
00130 
00131 #endif

Generated on Thu Mar 27 19:04:14 2008 by  doxygen 1.4.6