00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "wvhconf.h"
00011 #include "wvstream.h"
00012
00013
00014
00015 WvHConf::WvHConf()
00016 : name("")
00017 {
00018 parent = NULL;
00019 init();
00020 }
00021
00022
00023 WvHConf::WvHConf(WvHConf *_parent, const WvString &_name)
00024 : name(_name)
00025 {
00026 parent = _parent;
00027 init();
00028 }
00029
00030
00031 void WvHConf::init()
00032 {
00033 children = NULL;
00034 defaults = NULL;
00035 generator = NULL;
00036
00037 dirty = child_dirty = false;
00038 notify = child_notify = false;
00039
00040 obsolete = child_obsolete = false;
00041 }
00042
00043
00044 WvHConf::~WvHConf()
00045 {
00046 if (children)
00047 delete children;
00048 if (generator)
00049 delete generator;
00050 }
00051
00052
00053
00054
00055
00056 WvHConf *WvHConf::top()
00057 {
00058 WvHConf *h = this;
00059 while (h->parent)
00060 h = h->parent;
00061 return h;
00062 }
00063
00064
00065
00066
00067 WvHConfKey WvHConf::full_key() const
00068 {
00069 WvHConfKey k;
00070 const WvHConf *h = this;
00071
00072 do
00073 {
00074 k.prepend(new WvString(h->name), true);
00075 h = h->parent;
00076 } while (h);
00077
00078 return k;
00079 }
00080
00081
00082
00083
00084 WvHConf *WvHConf::gen_top()
00085 {
00086 WvHConf *h = this;
00087 while (h->parent && !h->generator)
00088 h = h->parent;
00089
00090 return h;
00091 }
00092
00093
00094
00095
00096
00097
00098
00099 WvHConfKey WvHConf::gen_full_key() const
00100 {
00101 WvHConfKey k;
00102 const WvHConf *h = this;
00103
00104 while (h && !h->generator)
00105 {
00106 k.prepend(new WvString(h->name), true);
00107 h = h->parent;
00108 };
00109
00110 return k;
00111 }
00112
00113
00114
00115 WvHConf *WvHConf::find(const WvHConfKey &key)
00116 {
00117 if (key.isempty())
00118 return this;
00119 if (!children)
00120 return NULL;
00121
00122 WvHConf *h = (*children)[*key.first()];
00123 if (!h)
00124 return NULL;
00125 else
00126 return h->find(key.skip(1));
00127 }
00128
00129
00130
00131 WvHConf *WvHConf::find_make(const WvHConfKey &key)
00132 {
00133 if (key.isempty())
00134 return this;
00135 if (children)
00136 {
00137 WvHConf *h = (*children)[*key.first()];
00138 if (h)
00139 return h->find_make(key.skip(1));
00140 }
00141
00142
00143 WvHConf *htop = gen_top();
00144 if (htop->generator)
00145 return htop->generator->make_tree(this, key);
00146 else
00147 return WvHConfGen().make_tree(this, key);
00148 }
00149
00150
00151
00152
00153
00154
00155
00156
00157 WvHConf *WvHConf::find_default(WvHConfKey *_k) const
00158 {
00159 WvHConfKey tmp_key;
00160 WvHConfKey &k = (_k ? *_k : tmp_key);
00161 WvHConf *def;
00162
00163
00164
00165 if (defaults)
00166 {
00167
00168 def = defaults->find(k);
00169 if (def)
00170 return def;
00171 }
00172
00173 if (parent)
00174 {
00175
00176 WvString s1(name);
00177 k.prepend(&s1, false);
00178 def = parent->find_default(&k);
00179 k.unlink_first();
00180 if (def)
00181 return def;
00182
00183
00184 WvString s2("*");
00185 k.prepend(&s2, false);
00186 def = parent->find_default(&k);
00187 k.unlink_first();
00188 if (def)
00189 return def;
00190 }
00191
00192 return NULL;
00193 }
00194
00195
00196 void WvHConf::set_without_notify(const WvString &s)
00197 {
00198 value = s;
00199 value.unique();
00200 }
00201
00202
00203 void WvHConf::set(const WvString &s)
00204 {
00205 WvHConf *h;
00206
00207 if (s == value)
00208 return;
00209
00210 set_without_notify(s);
00211
00212 if (dirty && notify)
00213 return;
00214
00215 dirty = notify = true;
00216
00217
00218
00219
00220 h = parent;
00221 while (h && (!h->child_dirty || !h->child_notify))
00222 {
00223 h->child_dirty = h->child_notify = true;
00224 h = h->parent;
00225 }
00226 }
00227
00228
00229 void WvHConf::do_notify()
00230 {
00231 WvHConf *h;
00232
00233 dirty = notify = true;
00234
00235 h = parent;
00236 while (h && (!h->child_dirty || !h->child_notify))
00237 {
00238 h->child_dirty = h->child_notify = true;
00239 h = h->parent;
00240 }
00241 }
00242
00243
00244 const WvString &WvHConf::printable() const
00245 {
00246 WvHConf *def;
00247
00248 if (!!value)
00249 return value;
00250
00251 def = find_default();
00252 if (def)
00253 return def->printable();
00254
00255
00256 return value;
00257 }
00258
00259
00260 void WvHConf::load()
00261 {
00262 if (generator)
00263 generator->load();
00264 else if (children)
00265 {
00266 WvHConfDict::Iter i(*children);
00267 for (i.rewind(); i.next(); )
00268 i->load();
00269 }
00270 }
00271
00272
00273 void WvHConf::save()
00274 {
00275 if (!dirty && !child_dirty)
00276 return;
00277
00278 if (generator)
00279 generator->save();
00280 else if (children && child_dirty)
00281 {
00282 WvHConfDict::Iter i(*children);
00283 for (i.rewind(); i.next(); )
00284 i->save();
00285 }
00286 }
00287
00288
00289 void WvHConf::dump(WvStream &s)
00290 {
00291 if (!!value)
00292 {
00293 s.print(" %s%s%s%s%s%s %s = %s\n",
00294 child_dirty, dirty,
00295 child_notify, notify,
00296 child_obsolete, obsolete,
00297 full_key(), value);
00298 }
00299
00300 if (children)
00301 {
00302 WvHConfDict::Iter i(*children);
00303 for (i.rewind(); i.next(); )
00304 i->dump(s);
00305 }
00306 }
00307
00308