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
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
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
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
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
00201 typedef SingleOption<String> StringOption;
00202
00203
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
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
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
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
00337 #endif