ConfigHandler.hh

Go to the documentation of this file.
00001 //Copyright 2013 Ben Loer
00002 //This file is part of the ConfigHandler library
00003 //It is released under the terms of the GNU General Public License v3
00004 
00013 #ifndef CONFIGHANDLER_h
00014 #define CONFIGHANDLER_h 1
00015 #include <string>
00016 #include <set>
00017 #include <vector>
00018 #include "ParameterList.hh"
00019 #include "phrase.hh"
00020 
00023 
00035 class ConfigHandler : public ParameterList{
00036 public:
00038   static ConfigHandler* const GetInstance()
00039   { 
00040     static ConfigHandler config;
00041     return &config;
00042   }
00043     
00061   template<class Action> 
00062   int AddCommandSwitch(char shortname,
00063                        const std::string& longname,
00064                        const std::string& helptext,
00065                        Action action,
00066                        const std::string& parameter = "");
00068   int RemoveCommandSwitch(char shortname, const std::string& longname);
00069   
00071   void PrintSwitches(bool quit=true, std::ostream& out = std::cout,
00072                      bool escape=false);
00074   void SetProgramUsageString(const std::string& usage){ _program_usage=usage;}
00076   std::string GetProgramUsageString(){ return _program_usage; }
00078   void SetProgramDescription(const std::string& d){ _program_description=d;}
00080   std::string GetProgramDescription(){ return _program_description; }
00081   
00084   int ProcessCommandLine(int& argc, char** argv);
00085   
00088   int GetNCommandArgs() { return _cmd_args.size(); }
00089   
00091   const char* GetCommandArg(size_t n) { return _cmd_args.at(n); }
00092   
00093   //functions for loading a saved parameter list
00095   void SetSavedCfgFile(const std::string& fname){ _saved_cfg = fname; }
00097   const std::string& GetSavedCfgFile(){ return _saved_cfg; }
00099   template<class T> bool LoadCreateParameterList(T*& par, std::string key="",
00100                                                  bool registerme = false);
00102   template<class T> bool LoadParameterList(T* par, std::string key="",
00103                                            bool registerme = false);
00105   void SetNotes(const std::string& newnotes) { _notes = newnotes; }
00107   const std::string& GetNotes(){ return _notes; }
00108 
00110   void SetDefaultCfgFile(const std::string& file) { _default_cfg_file = file; }
00112   const std::string& GetDefaultCfgFile(){ return _default_cfg_file; }
00113   
00114   //search multiple paths for a config file
00115   std::string FindConfigFile(const std::string& fname);
00116  
00117 private:
00118   std::string _program_usage;      
00119   std::string _program_description; 
00120 
00121   std::string _notes;                
00122   std::string _default_cfg_file;    
00123   std::string _saved_cfg;             
00124 
00125   std::vector<std::string> _cfg_paths; 
00126   
00128   ConfigHandler(); 
00130   ~ConfigHandler();
00131   
00133   ConfigHandler(const ConfigHandler& right) : ParameterList(),
00134                                               _switches(right._switches) {}
00136   ConfigHandler& operator=(const ConfigHandler& right)
00137   { _switches = right._switches; return *this; }
00138   
00139   std::vector<char*> _cmd_args;  
00140   
00141   
00145   class VCommandSwitch{
00146   public:
00147     char shortname;               
00148     std::string longname;         
00149     std::string helptext;         
00150     std::string parameter;        
00151 
00152     VCommandSwitch(char short_name, const std::string& long_name,
00153                    const std::string& help_text, const std::string& par) :
00154       shortname(short_name), longname(long_name), helptext(help_text), 
00155       parameter(par) {}
00157     virtual ~VCommandSwitch() {}
00159     virtual int Process(const char* arg) = 0;
00160   };
00161   
00167   template<class Action> class CommandSwitch : public VCommandSwitch{
00168     Action do_action;
00169   public:
00170     CommandSwitch(char short_name, const std::string& long_name,
00171                   const std::string& help_text, const std::string& par,
00172                   Action action) : 
00173       VCommandSwitch(short_name, long_name, help_text, par), 
00174       do_action(action) {}
00175     virtual ~CommandSwitch() {}
00176     virtual int Process(const char* arg);
00177   };
00178   
00180   struct OrderCommandSwitchPointers{
00181     bool operator()(VCommandSwitch* a, VCommandSwitch* b);
00182   };
00183 
00184   typedef std::set<VCommandSwitch*, OrderCommandSwitchPointers> SwitchSet;
00185   SwitchSet _switches; 
00186 };
00187 
00188 //templates must be defined in header
00189 template<class Action> 
00190 int ConfigHandler::AddCommandSwitch(char shortname,
00191                                     const std::string& longname,
00192                                     const std::string& helptext,
00193                                     Action action,
00194                                     const std::string& parameter)
00195 {
00196   //Make sure both shortname and longname aren't empty
00197   if(shortname == ' ' && longname == ""){
00198     std::cerr<<"Error: At least one of shortname and longname must be non-empty for switches!"<<std::endl;
00199     return -1;
00200   }
00201   //Make sure there isn't already a registered switch  with the same keys
00202   for( SwitchSet::iterator it = _switches.begin(); it != _switches.end(); it++){
00203     if( shortname != ' ' && shortname == (*it)->shortname){
00204       std::cerr<<"Switch already registered with shortname '"
00205                <<shortname<<"'"<<std::endl;
00206       return -2;
00207     }
00208     else if( longname != "" && longname == (*it)->longname){
00209       std::cerr<<"Switch already registered with longname \""
00210                <<longname<<"\""<<std::endl;
00211       return -3;
00212     }
00213   }
00214   _switches.insert(new CommandSwitch<Action>(shortname, longname, helptext,
00215                                              parameter, action) );
00216   return 0;
00217 }
00218 
00219 
00220 template<class Action> inline
00221 int ConfigHandler::CommandSwitch<Action>::Process(const char* arg)
00222 {
00223   return do_action(arg);
00224 }
00225 
00226 
00227 //load a saved parameter list
00228 template<class T> inline
00229 bool ConfigHandler::LoadCreateParameterList(T*& par, 
00230                                             std::string key, 
00231                                             bool registerme)
00232 {
00233   if(!par){
00234     boost::shared_ptr<VParameterNode> ptr(par = new T);
00235     //..par = ptr.get();
00236     _deleter.push_back(ptr);
00237   }
00238   return LoadParameterList(par, key, registerme);
00239 }
00240 
00241 template<class T> inline 
00242 bool ConfigHandler::LoadParameterList(T* par,
00243                                       std::string key,
00244                                       bool registerme)
00245 {
00246   bool err=1;
00247   if(key == "")
00248     key = par->GetDefaultKey();
00249   if(registerme)
00250     RegisterParameter(key, *par);
00251   if(_saved_cfg != "")
00252     err = !(par->ReadFromFile(_saved_cfg.c_str(), key, true));
00253   return err;
00254 }
00255 
00257 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on 20 Jun 2014 for daqman by  doxygen 1.6.1