00001
00002 #include "cafe/Config.hpp"
00003
00004 #include "TEnv.h"
00005 #include "TOrdCollection.h"
00006 #include "TObjArray.h"
00007 #include "TString.h"
00008 #include "TObjString.h"
00009 #include "THashList.h"
00010 #include "TDirectory.h"
00011 #include "TSystem.h"
00012
00013 #include <memory>
00014 #include <iostream>
00015 #include <set>
00016 #include <cstdlib>
00017
00018 namespace cafe {
00019
00020 Config::Config(const std::string& name)
00021 : _name(name)
00022 {}
00023
00024 Config::~Config()
00025 {}
00026
00027 std::string Config::get(const std::string& key, const std::string& def)
00028 {
00029 return getEnv().GetValue((_name + '.' + key).c_str(), def.c_str());
00030 }
00031
00032 int Config::get(const std::string& key, int def)
00033 {
00034 return getEnv().GetValue((_name + '.' + key).c_str(), def);
00035 }
00036
00037 double Config::get(const std::string& key, double def)
00038 {
00039 return getEnv().GetValue((_name + '.' + key).c_str(), def);
00040 }
00041
00042 std::vector<std::string> Config::getVString(const std::string& key, const std::string& delim)
00043 {
00044
00045 TString s(get(key, "").c_str());
00046 std::vector<std::string> result;
00047 TObjArray *tokens = s.Tokenize(delim.c_str());
00048 {
00049 TIter iter(tokens);
00050 while(TObject *p = iter.Next()) {
00051 TObjString *item = (TObjString*)p;
00052 result.push_back(item->GetString().Data());
00053 }
00054 }
00055 delete tokens;
00056 return result;
00057 }
00058
00059 std::vector<float> Config::getVFloat(const std::string& key, const std::string& delim)
00060 {
00061
00062 TString s(get(key, "").c_str());
00063 std::vector<float> result;
00064 TObjArray *tokens = s.Tokenize(delim.c_str());
00065 TIter iter(tokens);
00066 while(TObject *p = iter.Next()) {
00067 TObjString *item = (TObjString*)p;
00068 result.push_back(atof(item->GetString().Data()));
00069 }
00070 delete tokens;
00071 return result;
00072 }
00073
00074 std::vector<int> Config::getVInt(const std::string& key, const std::string& delim)
00075 {
00076
00077 TString s(get(key, "").c_str());
00078 std::vector<int> result;
00079 TObjArray *tokens = s.Tokenize(delim.c_str());
00080 TIter iter(tokens);
00081 while(TObject *p = iter.Next()) {
00082 TObjString *item = (TObjString*)p;
00083 result.push_back(strtol(item->GetString().Data(),0,0));
00084 }
00085 delete tokens;
00086 return result;
00087 }
00088
00089 void Config::set(const std::string& key, const std::string& value)
00090 {
00091 getEnv().SetValue(key.c_str(), value.c_str());
00092 }
00093
00094 void Config::dumpConfig(std::ostream& stream)
00095 {
00096 TIter next(getEnv().GetTable());
00097 TEnvRec *er;
00098 static const char *lc[] = { "Global", "User", "Local", "Changed" };
00099
00100 stream << "cafe::Config: Dumping configuration settings" << std::endl;
00101 while ((er = (TEnvRec*) next()))
00102 stream << Form("%-25s: %-30s [%s]",
00103 er->GetName(),er->GetValue(),lc[er->GetLevel()]) << std::endl;
00104 stream << "cafe::Config: End of configuration settings" << std::endl;
00105
00106 return;
00107 }
00108
00109 void Config::dumpConfig(TDirectory* const dir, std::string const name)
00110 {
00111 if (dir) {
00112 TObjArray array(getEnv().GetTable()->GetSize());
00113 array.SetOwner(kTRUE);
00114
00115 TIter next(getEnv().GetTable());
00116 TEnvRec *er;
00117 static const char *lc[] = { "Global", "User", "Local", "Changed" };
00118
00119 size_t index = 0;
00120 while ((er = (TEnvRec*) next())) {
00121 TObjString* str = new TObjString(Form("%-25s: %-30s [%s]",
00122 er->GetName(),
00123 er->GetValue(),
00124 lc[er->GetLevel()]));
00125 array[index] = str;
00126 ++index;
00127 }
00128
00129 dir->cd();
00130 array.Write(name.c_str(),TObject::kSingleKey);
00131
00132 }
00133
00134 return;
00135 }
00136
00137 namespace {
00138 std::auto_ptr<TEnv> _cleanup;
00139 }
00140
00141 TEnv& Config::getEnv()
00142 {
00143 static TEnv *_env;
00144
00145 if(_env == 0) {
00146
00147
00148
00149
00150
00151 if(const char *filename = gSystem->Getenv("CAFE_CONFIG")) {
00152 std::cout << "Reading configuration file: " << filename << std::endl;
00153 _env = new TEnv(filename);
00154 if(_env->GetTable()->GetSize() == 0) {
00155 delete _env;
00156 _env = 0;
00157 }
00158 }
00159
00160 if(_env == 0) {
00161 _env = new TEnv("./cafe.config");
00162 if(_env->GetTable()->GetSize() == 0) {
00163 delete _env;
00164 _env = 0;
00165 }
00166 }
00167
00168 if(_env == 0) {
00169 std::string ctx;
00170 if(const char *c = getenv("SRT_PRIVATE_CONTEXT")) {
00171 ctx += c;
00172 }
00173 ctx += "./cafe.config";
00174 _env = new TEnv(ctx.c_str());
00175 }
00176
00177
00178
00179
00180 std::set<std::string> _files_included;
00181
00182 bool add_more = false;
00183 do {
00184 add_more = false;
00185 TString s(_env->GetValue("cafe.Include", "")) ;
00186 std::auto_ptr<TObjArray> includes(s.Tokenize(" ,\t"));
00187 TIter iter(includes.get());
00188 while(TObject *p = iter.Next()) {
00189 std::string filename(((TObjString*)p)->GetString().Data());
00190 if(_files_included.count(filename) > 0) continue;
00191 std::cout << "Including configuration file: " << filename << std::endl;
00192 _env->ReadFile((filename).c_str(), kEnvLocal);
00193 _files_included.insert(filename);
00194 add_more = true;
00195 }
00196 } while(add_more);
00197
00198 _cleanup = std::auto_ptr<TEnv>(_env);
00199 }
00200 return *_env;
00201 }
00202 }
00203