wibble 0.1.28
|
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 // Elements added to this engine 00045 std::vector<OptionGroup*> m_groups; 00046 std::vector<Option*> m_options; 00047 std::vector<Engine*> m_commands; 00048 00049 // Parse tables for commandline options 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 // Command selected with the non-switch command, if any were found, else 00055 // NULL 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 // Rebuild the parse tables 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 // Set to true if the engine should not be documented 00228 bool hidden; 00229 00230 // Set to true if no switches should be parsed after the first 00231 // non-switch argument, and they should be just left in the argument 00232 // list 00233 bool no_switches_after_first_arg; 00234 00235 00236 friend class Parser; 00237 }; 00238 00239 } 00240 } 00241 00242 // vim:set ts=4 sw=4: 00243 #endif