00001
00002
00003
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
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
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
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
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
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
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
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