00001 #include "CfgPromptConfigurable.h"
00002 #include "CfgDialog.h"
00003 #include "MessageService/MsgService.h"
00004 #include <string.h>
00005 #include <stdlib.h>
00006 #include <typeinfo>
00007 #include <assert.h>
00008
00009 ClassImp(CfgPromptConfigurable)
00010 CVSID( " $Id: CfgPromptConfigurable.cxx,v 1.5 2008/10/10 23:34:22 bckhouse Exp $" );
00011
00012 CfgPromptConfigurable::CfgPromptConfigurable()
00013 {
00062 }
00063
00064 void CfgPromptConfigurable::InitializeConfig(const Registry& initConfig)
00065 {
00066 fConfig.UnLockKeys();
00067 fConfig.UnLockValues();
00068 fConfig.Clear();
00069 fConfig=initConfig;
00070 fConfig.SetDirty(false);
00071 fConfig.LockKeys();
00072 fConfig.UnLockValues();
00073
00074
00075 fDefaultConfig=initConfig;
00076
00077 ConfigModified();
00078 }
00079
00080 Bool_t CfgPromptConfigurable::Split(const char* line, char sep, string& a, string& b)
00081 {
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 bool split = false;
00099 a = "";
00100 b = "";
00101 const char* c = line;
00102 while(*c != '\0') {
00103 if(*c == sep) {
00104 split=true;
00105 break;
00106 }
00107 a+=(*c);
00108 ++c;
00109 }
00110 while(*c == sep) { ++c; };
00111 b = c;
00112 return split;
00113 }
00114
00115 bool CfgPromptConfigurable::IsInt(const std::string& s, Int_t& i)
00116 {
00117
00118
00119
00120 const char* ss = s.c_str();
00121 char* endptr;
00122 double d = strtod(ss, &endptr);
00123 if (endptr==ss && d==0.0) return false;
00124
00125
00126 if (strchr(ss,'.')) return false;
00127 if (strchr(ss,'E')) return false;
00128 if (strchr(ss,'e')) return false;
00129
00130
00131 i = atoi(ss);
00132
00133 return true;
00134 }
00135
00136
00137
00138
00139 bool CfgPromptConfigurable::IsFloat(const std::string& s, Double_t& val)
00140 {
00141
00142
00143
00144 char* endptr;
00145 double d = strtod(s.c_str(), &endptr);
00146 if (endptr==s && d==0.0) return false;
00147
00148
00149 val = d;
00150 return true;
00151 }
00152
00153
00154 void CfgPromptConfigurable::Set(CfgDialog* d)
00155 {
00156
00157
00158
00159
00160
00161 bool deleteDialog = false;
00162 if (d==0) {
00163 d = new CfgDialog();
00164 deleteDialog = true;
00165 }
00166
00167
00168 d->SetDefault(fDefaultConfig);
00169 d->SetCurrent(fConfig);
00170
00171
00172 Registry r = d->Query();
00173 Set(r);
00174
00175
00176 if (deleteDialog) { delete d; d = 0; }
00177 }
00178
00179 void CfgPromptConfigurable::Set(const char* key, char val)
00180 { Registry r; r.Set(key,val); Set(r); }
00181
00182
00183 void CfgPromptConfigurable::Set(const char* key, const char* val)
00184 { Registry r; r.Set(key,val); Set(r); }
00185
00186
00187
00188 void CfgPromptConfigurable::Set(const char* key, double val)
00189 { Registry r; r.Set(key,val); Set(r); }
00190
00191
00192 void CfgPromptConfigurable::Set(const char* key, int val)
00193 { Registry r; r.Set(key,val); Set(r); }
00194
00195
00196 void CfgPromptConfigurable::Set(const char* key, const Registry& val )
00197 { Registry r; r.Set(key,val); Set(r); }
00198
00199
00200 void CfgPromptConfigurable::Set(const char* setstring)
00201 {
00202
00203
00204
00205 Registry r;
00206 string a,b;
00207 string line = setstring;
00208 bool split;
00209 do {
00210 split = Split(line,' ',a,b);
00211
00212
00213 string key, val;
00214 if(a.size()>0) {
00215 if(Split(a,'=',key,val)) {
00216 Int_t i;
00217 Double_t f;
00218 if(IsInt(val,i)) {
00219 r.Set(key.c_str(),i);
00220 } else if(IsFloat(val,f)) {
00221 r.Set(key.c_str(),f);
00222 } else {
00223 r.Set(key.c_str(),val.c_str());
00224 };
00225
00226
00227 } else {
00228 MSG("Configurable",Msg::kWarning) << "Can't parse fragment: " << a << endl;
00229 }
00230 }
00231
00232 line = b;
00233 } while ( split );
00234
00235
00236 Set(r);
00237 }
00238
00239
00240
00241 void CfgPromptConfigurable::Set(const Registry& stuff, Bool_t recursive)
00242 {
00243 if(SafeMerge(fConfig,stuff,recursive)) {
00244
00245 ConfigModified();
00246 fConfig.SetDirty(false);
00247 }
00248 }
00249
00250 Bool_t CfgPromptConfigurable::SafeMerge(Registry& modify,
00251 const Registry& stuff,
00252 Bool_t recursive )
00253 {
00258
00259
00260 if(modify.ValuesLocked()) {
00261 MSG("Configurable",Msg::kWarning) << "Configurable has values locked. Can't set:" << endl;
00262 MSG("Configurable",Msg::kWarning) << stuff << endl;
00263 return false;
00264 }
00265
00266
00267 bool modified = false;
00268
00269
00270 Registry::RegistryKey keyitr = stuff.Key();
00271 const char* key;
00272 while( (key = keyitr()) ) {
00273
00274
00275 if(!modify.KeyExists(key)) {
00276
00277
00278 if(modify.KeysLocked()) {
00279
00280
00281 MSG("Configurable",Msg::kWarning) << "Key " << key << " is not initialized in this Configurable. Skipping." << endl;
00282 MSG("Configurable",Msg::kInfo) << "Current key/values are:" <<endl;
00283 if( MsgService::Instance()->IsActive("Configurable",Msg::kInfo) )
00284 modify.PrettyPrint(std::cout);
00285
00286 MSG("Configurable",Msg::kFatal) << "\"" << key << "\" is an illegal key! Fix your script!" << endl;
00287 assert(0);
00288 continue;
00289
00290 } else {
00291
00292 }
00293
00294 } else {
00295
00296
00297
00298 if(modify.GetType(key)!=stuff.GetType(key)) {
00299 MSG("Configurable",Msg::kWarning) << "Key \"" << key << "\" is not initialized as type ("
00300 << modify.GetType(key).name()
00301 << ") but you've tried to set it to type ("
00302 << stuff.GetType(key).name()
00303 << ")" << endl;
00304 continue;
00305 }
00306
00307 if( modify.GetValueAsString(key)==stuff.GetValueAsString(key) ) {
00308
00309 continue;
00310 }
00311 }
00312
00313
00314 int vint;
00315 double vdouble;
00316 char vchar;
00317 const char* vcharstar;
00318 Registry vregistry;
00319
00320 const type_info& theType(modify.GetType(key));
00321
00322 if((theType==typeid(char))&&(stuff.Get(key,vchar))) modify.Set(key,vchar);
00323 if((theType==typeid(int))&&(stuff.Get(key,vint))) modify.Set(key,vint);
00324 if((theType==typeid(double))&&(stuff.Get(key,vdouble))) modify.Set(key,vdouble);
00325 if((theType==typeid(const char*))&&(stuff.Get(key,vcharstar))) modify.Set(key,vcharstar);
00326 if(stuff.GetTypeAsString(key) == "Registry"){
00327 if(stuff.Get(key,vregistry)) {
00328
00329 if(recursive) {
00330
00331 Registry old;
00332 if(modify.Get(key,old)) {
00333 Registry old;
00334
00335 old.UnLockValues();
00336 old.LockKeys();
00337 if(SafeMerge(old,vregistry)) modified = true;
00338 modify.Set(key,old);
00339 }
00340
00341 } else {
00342 modify.Set(key,vregistry);
00343 }
00344 }
00345 }
00346
00347 modified = true;
00348 };
00349
00350 return modified;
00351 }
00352