• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

options.h

Go to the documentation of this file.
00001 #ifndef WIBBLE_COMMANDLINE_OPTIONS_H
00002 #define WIBBLE_COMMANDLINE_OPTIONS_H
00003 
00004 #include <wibble/commandline/core.h>
00005 #include <string>
00006 #include <vector>
00007 
00008 namespace wibble {
00009 namespace commandline {
00010 
00011 // Types of values for the command line options
00012 
00013 struct Bool
00014 {
00015     typedef bool value_type;
00016     static bool parse(const std::string& val);
00017 
00018     static bool toBool(const value_type& val);
00019     static int toInt(const value_type& val);
00020     static std::string toString(const value_type& val);
00021 };
00022 
00023 struct Int
00024 {
00025     typedef int value_type;
00026     static int parse(const std::string& val);
00027 
00028     static bool toBool(const value_type& val);
00029     static int toInt(const value_type& val);
00030     static std::string toString(const value_type& val);
00031 };
00032 
00033 struct String
00034 {
00035     typedef std::string value_type;
00036     static std::string parse(const std::string& val);
00037 
00038     static bool toBool(const value_type& val);
00039     static int toInt(const value_type& val);
00040     static std::string toString(const value_type& val);
00041 };
00042 
00043 struct ExistingFile
00044 {
00045     typedef std::string value_type;
00046     static std::string parse(const std::string& val);
00047     static std::string toString(const value_type& val);
00048 };
00049 
00051 class Option : public Managed
00052 {
00053     std::string m_name;
00054     mutable std::string m_fullUsage;
00055 
00056 protected:
00057     bool m_isset;
00058 
00059     Option(const std::string& name) : m_name(name), m_isset(false) {}
00060     Option(const std::string& name,
00061             char shortName,
00062             const std::string& longName,
00063             const std::string& usage = std::string(),
00064             const std::string& description = std::string())
00065         : m_name(name), m_isset(false), usage(usage), description(description)
00066     {
00067         if (shortName != 0)
00068             shortNames.push_back(shortName);
00069         if (!longName.empty())
00070             longNames.push_back(longName);
00071     }
00072 
00084     virtual ArgList::iterator parse(ArgList& list, ArgList::iterator begin) = 0;
00085 
00091     virtual bool parse(const std::string& param) = 0;
00092 
00093 public:
00094     Option();
00095     virtual ~Option() {}
00096 
00097     bool isSet() const { return m_isset; }
00098     const std::string& name() const { return m_name; }
00099 
00100     void addAlias(char c) { shortNames.push_back(c); }
00101     void addAlias(const std::string& str) { longNames.push_back(str); }
00102 
00104     const std::string& fullUsage() const;
00105     std::string fullUsageForMan() const;
00106 
00107     std::vector<char> shortNames;
00108     std::vector<std::string> longNames;
00109 
00110     std::string usage;
00111     std::string description;
00112 
00113     // Set to true if the option should not be documented
00114     bool hidden;
00115 
00116     friend class OptionGroup;
00117     friend class Engine;
00118 };
00119 
00121 class BoolOption : public Option
00122 {
00123     bool m_value;
00124 
00125 protected:
00126     BoolOption(const std::string& name)
00127         : Option(name), m_value(false) {}
00128     BoolOption(const std::string& name,
00129             char shortName,
00130             const std::string& longName,
00131             const std::string& usage = std::string(),
00132             const std::string& description = std::string())
00133         : Option(name, shortName, longName, usage, description), m_value(false) {}
00134 
00135     virtual ArgList::iterator parse(ArgList&, ArgList::iterator begin) { m_isset = true; m_value = true; return begin; }
00136     virtual bool parse(const std::string&) { m_isset = true; m_value = true; return false; }
00137 
00138 public:
00139     bool boolValue() const { return m_value; }
00140     std::string stringValue() const { return m_value ? "true" : "false"; }
00141 
00142     friend class OptionGroup;
00143     friend class Engine;
00144 };
00145 
00146 template<typename T>
00147 class SingleOption : public Option
00148 {
00149 protected:
00150     typename T::value_type m_value;
00151 
00152     SingleOption(const std::string& name)
00153         : Option(name)
00154     {
00155         usage = "<val>";
00156     }
00157     SingleOption(const std::string& name,
00158             char shortName,
00159             const std::string& longName,
00160             const std::string& usage = std::string(),
00161             const std::string& description = std::string())
00162         : Option(name, shortName, longName, usage, description)
00163     {
00164         if (usage.empty())
00165             this->usage = "<val>";
00166     }
00167 
00168     ArgList::iterator parse(ArgList& list, ArgList::iterator begin)
00169     {
00170         if (begin == list.end())
00171             throw exception::BadOption("no string argument found");
00172         m_value = T::parse(*begin);
00173         m_isset = true;
00174         // Remove the parsed element
00175         return list.eraseAndAdvance(begin);
00176     }
00177     bool parse(const std::string& param)
00178     {
00179         m_value = T::parse(param);
00180         m_isset = true;
00181         return true;
00182     }
00183 
00184 public:
00185         void setValue( const typename T::value_type &a ) {
00186             m_value = a;
00187         }
00188 
00189     typename T::value_type value() const { return m_value; }
00190 
00191     // Deprecated
00192     bool boolValue() const { return T::toBool(m_value); }
00193     int intValue() const { return T::toInt(m_value); }
00194     std::string stringValue() const { return T::toString(m_value); }
00195 
00196     friend class OptionGroup;
00197     friend class Engine;
00198 };
00199 
00200 // Option needing a compulsory string value
00201 typedef SingleOption<String> StringOption;
00202 
00203 // Option needing a compulsory int value
00204 struct IntOption : public SingleOption<Int>
00205 {
00206 protected:
00207     IntOption(const std::string& name) : SingleOption<Int>(name)
00208     {
00209         m_value = 0;
00210     }
00211     IntOption(const std::string& name,
00212             char shortName,
00213             const std::string& longName,
00214             const std::string& usage = std::string(),
00215             const std::string& description = std::string())
00216         : SingleOption<Int>(name, shortName, longName, usage, description)
00217     {
00218         m_value = 0;
00219     }
00220 public:
00221     friend class OptionGroup;
00222     friend class Engine;
00223 };
00224 
00228 typedef SingleOption<ExistingFile> ExistingFileOption;
00229 
00230 
00231 // Option that can be specified multiple times
00232 template<typename T>
00233 class VectorOption : public Option
00234 {
00235     std::vector< typename T::value_type > m_values;
00236 
00237 protected:
00238     VectorOption(const std::string& name)
00239         : Option(name)
00240     {
00241         usage = "<val>";
00242     }
00243     VectorOption(const std::string& name,
00244             char shortName,
00245             const std::string& longName,
00246             const std::string& usage = std::string(),
00247             const std::string& description = std::string())
00248         : Option(name, shortName, longName, usage, description)
00249     {
00250         if (usage.empty())
00251             this->usage = "<val>";
00252     }
00253 
00254     ArgList::iterator parse(ArgList& list, ArgList::iterator begin)
00255     {
00256         if (begin == list.end())
00257             throw exception::BadOption("no string argument found");
00258         m_isset = true;
00259         m_values.push_back(T::parse(*begin));
00260         // Remove the parsed element
00261         return list.eraseAndAdvance(begin);
00262     }
00263     bool parse(const std::string& param)
00264     {
00265         m_isset = true;
00266         m_values.push_back(T::parse(param));
00267         return true;
00268     }
00269 
00270 public:
00271     bool boolValue() const { return !m_values.empty(); }
00272     const std::vector< typename T::value_type >& values() const { return m_values; }
00273 
00274     friend class OptionGroup;
00275     friend class Engine;
00276 };
00277 
00278 
00282 class OptionGroup : public Managed
00283 {
00284     MemoryManager* m_manager;
00285 
00286 protected:
00287     OptionGroup(MemoryManager* mman = 0, const std::string& description = std::string())
00288         : m_manager(mman), description(description), hidden(false) {}
00289 
00290 public:
00291     Option* add(Option* o) { options.push_back(o); return o; }
00292 
00293     std::vector<Option*> options;
00294 
00295     std::string description;
00296 
00297     // Set to true if the option group should not be documented
00298     bool hidden;
00299 
00303     template<typename T>
00304     T* create(const std::string& name,
00305             char shortName,
00306             const std::string& longName,
00307             const std::string& usage = std::string(),
00308             const std::string& description = std::string())
00309     {
00310         T* item = new T(name, shortName, longName, usage, description);
00311         if (m_manager) m_manager->add(item);
00312         return item;
00313     }
00314 
00318     template<typename T>
00319     T* add(const std::string& name,
00320             char shortName,
00321             const std::string& longName,
00322             const std::string& usage = std::string(),
00323             const std::string& description = std::string())
00324     {
00325         T* res = create<T>(name, shortName, longName, usage, description);
00326         add(res);
00327         return res;
00328     }
00329 
00330     friend class Engine;
00331 };
00332 
00333 }
00334 }
00335 
00336 // vim:set ts=4 sw=4:
00337 #endif

Generated on Tue May 10 2011 16:51:50 for wibble by  doxygen 1.7.1