00001 #ifndef WIBBLE_COMMANDLINE_ENGINE_H
00002 #define WIBBLE_COMMANDLINE_ENGINE_H
00003
00004 #include <wibble/commandline/options.h>
00005 #include <string>
00006 #include <vector>
00007 #include <map>
00008 #include <iosfwd>
00009
00010 namespace wibble {
00011 namespace commandline {
00012
00013 #if 0
00014 -- This help is left around to be reintegrated when I found something
00015 appropriate. It documents the general behavior of functions in the form
00016 ArgList::iterator parse(ArgList& list, ArgList::iterator begin);
00017
00027 #endif
00028
00038 class Engine : public Managed
00039 {
00040 MemoryManager* m_manager;
00041 std::string m_name;
00042
00043 protected:
00044
00045 std::vector<OptionGroup*> m_groups;
00046 std::vector<Option*> m_options;
00047 std::vector<Engine*> m_commands;
00048
00049
00050 std::map<char, Option*> m_short;
00051 std::map<std::string, Option*> m_long;
00052 std::map<std::string, Engine*> m_aliases;
00053
00054
00055
00056 Engine* m_found_command;
00057
00058 void addWithoutAna(Option* o);
00059 void addWithoutAna(const std::vector<Option*>& o);
00060 void add(const std::string& alias, Engine* o);
00061
00062
00063 void rebuild();
00064
00072 std::pair<ArgList::iterator, bool> parseFirstIfKnown(ArgList& list, ArgList::iterator begin);
00073
00074 #if 0
00075
00076 ArgList::iterator parseConsecutiveSwitches(ArgList& list, ArgList::iterator begin);
00077 #endif
00078
00080 ArgList::iterator parseKnownSwitches(ArgList& list, ArgList::iterator begin);
00081
00089 ArgList::iterator parseList(ArgList& list) { return parse(list, list.begin()); }
00090
00095 ArgList::iterator parse(ArgList& list, ArgList::iterator begin);
00096
00097
00098 Engine(MemoryManager* mman = 0, const std::string& name = std::string(),
00099 const std::string& usage = std::string(),
00100 const std::string& description = std::string(),
00101 const std::string& longDescription = std::string())
00102 : m_manager(mman), m_name(name), m_found_command(0), primaryAlias(name),
00103 usage(usage), description(description), longDescription(longDescription), hidden(false),
00104 no_switches_after_first_arg(false) {}
00105
00106 public:
00107 const std::string& name() const { return m_name; }
00108
00110 Option* add(Option* o);
00111
00113 OptionGroup* add(OptionGroup* group);
00114
00116 Engine* add(Engine* o);
00117
00121 template<typename T>
00122 T* create(const std::string& name,
00123 char shortName,
00124 const std::string& longName,
00125 const std::string& usage = std::string(),
00126 const std::string& description = std::string())
00127 {
00128 T* item = new T(name, shortName, longName, usage, description);
00129 if (m_manager) m_manager->add(item);
00130 return item;
00131 }
00132
00136 template<typename T>
00137 T* add(const std::string& name,
00138 char shortName,
00139 const std::string& longName,
00140 const std::string& usage = std::string(),
00141 const std::string& description = std::string())
00142 {
00143 T* res = create<T>(name, shortName, longName, usage, description);
00144 add(res);
00145 return res;
00146 }
00147
00151 OptionGroup* createGroup(const std::string& description)
00152 {
00153 OptionGroup* g = new OptionGroup(m_manager, description);
00154 if (m_manager) m_manager->add(g);
00155 return g;
00156 }
00157
00161 OptionGroup* addGroup(const std::string& description)
00162 {
00163 return add(createGroup(description));
00164 }
00165
00169 Engine* createEngine(const std::string& name,
00170 const std::string& usage = std::string(),
00171 const std::string& description = std::string(),
00172 const std::string& longDescription = std::string())
00173 {
00174 Engine* item = new Engine(m_manager, name, usage, description, longDescription);
00175 if (m_manager) m_manager->add(item);
00176 return item;
00177 }
00178
00182 Engine* addEngine(const std::string& name,
00183 const std::string& usage = std::string(),
00184 const std::string& description = std::string(),
00185 const std::string& longDescription = std::string())
00186 {
00187 return add(createEngine(name, usage, description, longDescription));
00188 }
00189
00191 const std::vector<OptionGroup*>& groups() const { return m_groups; }
00192
00194 const std::vector<Option*>& options() const { return m_options; }
00195
00197 const std::vector<Engine*>& commands() const { return m_commands; }
00198
00199 Engine* command(const std::string& name) const
00200 {
00201 std::map<std::string, Engine*>::const_iterator i = m_aliases.find(name);
00202 if (i == m_aliases.end())
00203 return 0;
00204 else
00205 return i->second;
00206 }
00207
00209 bool hasOptions() const { return !m_groups.empty() || !m_options.empty(); }
00210
00215 Engine* foundCommand() const { return m_found_command; }
00216
00217
00218 void dump(std::ostream& out, const std::string& prefix = std::string());
00219
00220 std::string primaryAlias;
00221 std::vector<std::string> aliases;
00222 std::string usage;
00223 std::string description;
00224 std::string longDescription;
00225 std::string examples;
00226
00227
00228 bool hidden;
00229
00230
00231
00232
00233 bool no_switches_after_first_arg;
00234
00235
00236 friend class Parser;
00237 };
00238
00239 }
00240 }
00241
00242
00243 #endif