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

engine.h

Go to the documentation of this file.
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

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