Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

wvconfemu.cc

Go to the documentation of this file.
00001 /*
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Basic WvConf emulation layer for UniConf.
00006  */
00007 #include "wvconfemu.h"
00008 #include "wvstringtable.h"
00009 #include "wvfile.h"
00010 #include "strutils.h"
00011 
00012 
00013 /*
00014  * Parse the WvConf string "request"; pointers to the found section,
00015  * entry, and value fields are stored in *section, *entry, and *value
00016  * respectively, and request[] is modified.
00017  * 
00018  * For example, the string:
00019  *     [silly]billy=willy
00020  * is parsed into:
00021  *     section="silly"; entry="billy"; value="willy";
00022  * 
00023  * Returns 0 on success, -1 if the command is missing the '[', -2 if
00024  * the string is missing a ']', or -3 if the section or entry is
00025  * blank.  If a "value" is not found (ie. there is no equal sign
00026  * outside the [] brackets) this does not qualify as an error, but
00027  * *value is set to NULL.
00028 */
00029 static int parse_wvconf_request(char *request, char *&section,
00030                                 char *&entry, char *&value)
00031 {
00032     entry = value = NULL;
00033     
00034     section = strchr(request, '[');
00035     if (!section)
00036         return -1;
00037 
00038     section++;
00039     
00040     entry = strchr(section, ']');
00041     if (!entry)
00042         return -2;
00043 
00044     *entry++ = 0;
00045     
00046     value = strchr(entry, '=');
00047     if (value)
00048     {
00049         *value++ = 0;
00050         value = trim_string(value);
00051     }
00052     
00053     section = trim_string(section);
00054     entry = trim_string(entry);
00055     
00056     if (!*section)
00057         return -3;
00058     
00059     return 0;
00060 }
00061 
00062 
00063 static void do_setbool(void* userdata,
00064                        WvStringParm section, WvStringParm key,
00065                        WvStringParm oldval, WvStringParm newval)
00066 {
00067     bool* b = static_cast<bool*>(userdata);
00068 
00069     *b = true;
00070 }
00071 
00072 
00073 static void do_addname(void* userdata,
00074                        WvStringParm section, WvStringParm key,
00075                        WvStringParm oldval, WvStringParm newval)
00076 {
00077     (*(WvStringList *)userdata).append(new WvString(key), true);
00078 }
00079 
00080 
00081 static void do_addfile(void* userdata,
00082                        WvStringParm section, WvStringParm key,
00083                        WvStringParm oldval, WvStringParm newval)
00084 {
00085     WvFile tmp(WvString("/home/%s/%s", key, *(WvString *)userdata), 
00086                O_WRONLY | O_CREAT | O_TRUNC, 0600);
00087     if(tmp.isok())
00088     {
00089         if(!!newval)
00090             tmp.print("%s\n", newval);
00091         else
00092             tmp.print("%s\n", key);
00093     }
00094 }
00095 
00096 
00097 WvConfigEntryEmu *WvConfigSectionEmu::operator[] (WvStringParm s)
00098 {
00099     WvConfigEntryEmu* entry = entries[s];
00100 
00101     if (uniconf[s].exists())
00102     {
00103         if (!entry)
00104         {
00105             entry = new WvConfigEntryEmu(s, uniconf[s].get());
00106             entries.add(entry, true);
00107         }
00108         else
00109             entry->value = uniconf[s].get();
00110     }
00111     else
00112         entry = NULL;
00113 
00114     return entry;
00115 }
00116 
00117 
00118 const char *WvConfigSectionEmu::get(WvStringParm entry, const char *def_val)
00119 {
00120     WvString *value = new WvString(uniconf[entry].get(def_val));
00121     values.add(value, true);
00122     return value->cstr();
00123 }
00124 
00125 
00126 void WvConfigSectionEmu::set(WvStringParm entry, WvStringParm value)
00127 {
00128     uniconf[entry].set(value);
00129 }
00130 
00131 
00132 void WvConfigSectionEmu::quick_set(WvStringParm entry, WvStringParm value)
00133 {
00134     uniconf[entry].set(value);
00135 }
00136 
00137 
00138 bool WvConfigSectionEmu::isempty() const
00139 {
00140     return !uniconf.haschildren();
00141 }
00142 
00143 
00144 WvConfigSectionEmu::Iter::~Iter()
00145 {
00146 }
00147 
00148 
00149 void WvConfigSectionEmu::Iter::rewind()
00150 {
00151     iter.rewind();
00152     link.data = entry = NULL;
00153 }
00154 
00155 
00156 WvLink *WvConfigSectionEmu::Iter::next()
00157 {
00158     if (iter.next())
00159     {
00160         entry = sect[iter->key()];
00161         link.data = static_cast<void*>(entry);
00162         return &link;
00163     }
00164 
00165     return NULL;
00166 }
00167 
00168 
00169 WvLink *WvConfigSectionEmu::Iter::cur()
00170 {
00171     return &link;
00172 }
00173 
00174 
00175 WvConfigEntryEmu* WvConfigSectionEmu::Iter::ptr() const
00176 {
00177     return entry;
00178 }
00179 
00180 
00181 void* WvConfigSectionEmu::Iter::vptr() const
00182 {
00183     return link.data;
00184 }
00185 
00186 
00187 void WvConfEmu::notify(const UniConf &_uni, const UniConfKey &_key)
00188 {
00189     WvList<CallbackInfo>::Iter i(callbacks);
00190     WvString section(_key.first());
00191     WvString key(_key.removefirst());
00192 
00193     if (hold)
00194         return;
00195 
00196     for (i.rewind(); i.next(); )
00197     {
00198         if (((i->section && !i->section) || !strcasecmp(i->section, section))
00199             && ((i->key && !i->key) || !strcasecmp(i->key, key)))
00200         {
00201             WvString value = uniconf[section][key].get("");
00202             i->callback(i->userdata, section, key, i->last, value);
00203             i->last = value;
00204         }
00205     }
00206 }
00207 
00208 
00209 WvConfEmu::WvConfEmu(const UniConf& _uniconf):
00210     uniconf(_uniconf), sections(42), hold(false)
00211 {
00212     wvauthd = NULL;
00213     uniconf.add_callback(this,
00214                          UniConfCallback(this, &WvConfEmu::notify),
00215                          true);
00216 }
00217 
00218 
00219 void WvConfEmu::zap()
00220 {
00221     uniconf.remove();
00222 }
00223 
00224 
00225 bool WvConfEmu::isok() const
00226 {
00227     return !uniconf.isnull();
00228 }
00229 
00230 
00231 void WvConfEmu::load_file(WvStringParm filename)
00232 {
00233     UniConfRoot new_uniconf(WvString("ini:%s", filename));
00234 
00235     hold = true;
00236     new_uniconf.copy(uniconf, true);
00237     hold = false;
00238 }
00239 
00240 
00241 void WvConfEmu::save(WvStringParm filename)
00242 {
00243     UniConfRoot tmp_uniconf(WvString("ini:%s", filename));
00244 
00245     uniconf.copy(tmp_uniconf, true);
00246 }
00247 
00248 
00249 void WvConfEmu::save()
00250 {
00251     uniconf.commit();
00252 }
00253 
00254 
00255 void WvConfEmu::flush()
00256 {
00257     uniconf.commit();
00258 }
00259 
00260 
00261 WvConfigSectionEmu *WvConfEmu::operator[] (WvStringParm sect)
00262 {
00263     WvConfigSectionEmu* section = sections[sect];
00264 
00265     if (!section && uniconf[sect].exists())
00266     {
00267         section = new WvConfigSectionEmu(uniconf[sect], sect);
00268         sections.add(section, true);
00269     }
00270 
00271     return section;
00272 }
00273 
00274 
00275 void WvConfEmu::add_callback(WvConfCallback callback, void *userdata,
00276                              WvStringParm section, WvStringParm key,
00277                              void *cookie)
00278 {
00279     WvList<CallbackInfo>::Iter i(callbacks);
00280 
00281     if (!callback)
00282         return;
00283 
00284     for (i.rewind(); i.next(); )
00285     {
00286         if (i->cookie == cookie
00287             && i->section == section
00288             && i->key == key)
00289             return;
00290     }
00291 
00292     callbacks.append(new CallbackInfo(callback, userdata, section, key,
00293                                       cookie, get(section, key, "")),
00294                      true);
00295 }
00296 
00297 
00298 void WvConfEmu::del_callback(WvStringParm section, WvStringParm key, void *cookie)
00299 {
00300     WvList<CallbackInfo>::Iter i(callbacks);
00301 
00302     assert(cookie);
00303 
00304     for (i.rewind(); i.next(); )
00305     {
00306         if (i->cookie == cookie
00307             && i->section == section
00308             && i->key == key)
00309             i.xunlink();
00310     }
00311 }
00312 
00313 
00314 void WvConfEmu::add_setbool(bool *b, WvStringParm _section, WvStringParm _key)
00315 {
00316     add_callback(do_setbool, b, _section, _key, b);
00317 }
00318 
00319 
00320 void WvConfEmu::add_addname(WvStringList *list, WvStringParm sect, WvStringParm ent)
00321 {
00322     add_callback(do_addname, list, sect, ent, list);
00323 }
00324 
00325 
00326 void WvConfEmu::del_addname(WvStringList *list,
00327                             WvStringParm sect, WvStringParm ent)
00328 {
00329     del_callback(sect, ent, list);
00330 }
00331 
00332 
00333 void WvConfEmu::add_addfile(WvString *filename,
00334                             WvStringParm sect, WvStringParm ent)
00335 {
00336     add_callback(do_addfile, filename, sect, ent, NULL);
00337 }
00338 
00339 
00340 WvString WvConfEmu::getraw(WvString wvconfstr, int &parse_error)
00341 {
00342     char *section, *entry, *value;
00343     parse_error = parse_wvconf_request(wvconfstr.edit(),
00344                                        section, entry, value);
00345 
00346     if (parse_error)
00347         return WvString();
00348 
00349     return get(section, entry, value);
00350 }
00351 
00352 
00353 int WvConfEmu::getint(WvStringParm section, WvStringParm entry, int def_val)
00354 {
00355     return uniconf[section][entry].getint(def_val);
00356 }
00357 
00358 
00359 const char *WvConfEmu::get(WvStringParm section, WvStringParm entry,
00360                            const char *def_val)
00361 {
00362     WvString *value = new WvString(uniconf[section][entry].get(def_val));
00363     values.add(value, true);
00364     return value->cstr();
00365 }
00366 
00367 int WvConfEmu::fuzzy_getint(WvStringList &sect, WvStringParm entry,
00368                             int def_val)
00369 {
00370     WvString def_str(def_val);
00371     return check_for_bool_string(fuzzy_get(sect, entry, def_str));
00372 }
00373 
00374 
00375 const char *WvConfEmu::fuzzy_get(WvStringList &sect, WvStringParm entry,
00376                                  const char *def_val)
00377 {
00378     WvStringList::Iter i(sect);
00379     WvStringTable cache(5);
00380     WvConfigSection *s;
00381 
00382     for (i.rewind(); i.next(); )
00383     {
00384         for(s = (*this)[*i];
00385             s && !cache[s->name];
00386             s = (*s)["Inherits"] ? (*this)[(*s)["Inherits"]->value] : NULL)
00387         {
00388             const char *ret = s->get(entry);
00389             if (ret) return ret;
00390             cache.add(&s->name, false);
00391         }
00392     }
00393 
00394     return def_val;
00395 }
00396 
00397 void WvConfEmu::setraw(WvString wvconfstr, const char *&_value,
00398                        int &parse_error)
00399 {
00400     char *section, *entry, *value;
00401     parse_error = parse_wvconf_request(wvconfstr.edit(),
00402                                        section, entry, value);
00403     if (!parse_error)
00404     {
00405         set(section, entry, value);
00406         _value = get(section, entry, value);
00407     }
00408     else
00409         _value = NULL;
00410 }
00411 
00412 
00413 void WvConfEmu::setint(WvStringParm section, WvStringParm entry, int value)
00414 {
00415     uniconf[section][entry].setint(value);
00416 }
00417 
00418 
00419 void WvConfEmu::set(WvStringParm section, WvStringParm entry,
00420                     const char *value)
00421 {
00422     uniconf[section][entry].set(value);
00423 }
00424 
00425 
00426 void WvConfEmu::maybesetint(WvStringParm section, WvStringParm entry,
00427                             int value)
00428 {
00429     if (!get(section, entry, NULL))
00430         setint(section, entry, value);
00431 }
00432 
00433 
00434 void WvConfEmu::maybeset(WvStringParm section, WvStringParm entry,
00435                          const char *value)
00436 {
00437     if (get(section, entry, 0) == 0)
00438         set(section, entry, value);
00439 }
00440 
00441 
00442 void WvConfEmu::delete_section(WvStringParm section)
00443 {
00444     uniconf[section].set(WvString::null);
00445 }
00446 
00447 
00448 int WvConfEmu::check_for_bool_string(const char *s)
00449 {
00450     if (strcasecmp(s, "off") == 0
00451         || strcasecmp(s, "false") == 0
00452         || strncasecmp(s, "no", 2) == 0)   // also handles "none"
00453         return (0);
00454 
00455     if (strcasecmp(s, "on") == 0
00456         || strcasecmp(s, "true") == 0
00457         || strcasecmp(s, "yes") == 0)
00458         return (1);
00459 
00460     // not a special bool case, so just return the number
00461     return (atoi(s));
00462 }
00463 
00464 
00465 void WvConfEmu::Iter::rewind()
00466 {
00467     iter.rewind();
00468     link.data = NULL;
00469 }
00470 
00471 
00472 WvLink *WvConfEmu::Iter::next()
00473 {
00474     if (iter.next())
00475     {
00476         link.data = static_cast<void*>(conf[iter->key()]);
00477         return &link;
00478     }
00479 
00480     return NULL;
00481 }
00482 
00483 
00484 WvConfigSectionEmu* WvConfEmu::Iter::ptr() const
00485 {
00486     return conf[iter->key()];
00487 }
00488 

Generated on Sat Mar 13 14:55:35 2004 for WvStreams by doxygen 1.3.6-20040222