9 #include "wvstringtable.h"
14 #ifdef DEBUG_DEL_CALLBACK
34 static int parse_wvconf_request(
char *request,
char *§ion,
35 char *&entry,
char *&value)
39 section = strchr(request,
'[');
45 entry = strchr(section,
']');
51 value = strchr(entry,
'=');
68 static void do_setbool(
void *userdata,
69 WvStringParm section, WvStringParm key,
70 WvStringParm oldval, WvStringParm newval)
72 bool* b =
static_cast<bool*
>(userdata);
78 static void do_addname(
void *userdata,
79 WvStringParm section, WvStringParm key,
80 WvStringParm oldval, WvStringParm newval)
91 if (uniconf[s].exists())
96 entries.add(entry,
true);
99 entry->value = uniconf[s].
getme();
108 const char *WvConfigSectionEmu::get(WvStringParm entry,
const char *def_val)
113 WvString s(uniconf[entry].getme(def_val));
117 if (!sp) values.add(sp =
new WvString(s),
true);
122 void WvConfigSectionEmu::set(WvStringParm entry, WvStringParm value)
127 uniconf[entry].
setme(value);
129 uniconf[entry].
setme(WvString::null);
134 void WvConfigSectionEmu::quick_set(WvStringParm entry, WvStringParm value)
136 uniconf[entry].
setme(value);
140 bool WvConfigSectionEmu::isempty()
const
146 WvConfigSectionEmu::Iter::~Iter()
151 void WvConfigSectionEmu::Iter::rewind()
154 link.data = entry = NULL;
158 WvLink *WvConfigSectionEmu::Iter::next()
170 entry = sect[iter->fullkey(sect.uniconf)];
171 link.data =
static_cast<void*
>(entry);
181 WvLink *WvConfigSectionEmu::Iter::cur()
193 void *WvConfigSectionEmu::Iter::vptr()
const
210 for (i.rewind(); i.next(); )
212 if ((!i->section || !strcasecmp(i->section, section))
213 && (!i->key || !strcasecmp(i->key, key)))
215 i->callback(i->userdata, section, key,
WvString(), value);
221 WvConfEmu::WvConfEmu(
const UniConf &_uniconf)
222 : sections(42), hold(false), values(420), uniconf(_uniconf)
225 uniconf.add_callback(
this, wv::bind(&WvConfEmu::notify,
this, _1, _2),
231 WvConfEmu::~WvConfEmu()
237 #ifndef DEBUG_DEL_CALLBACK
244 fprintf(stderr,
" *** leftover callbacks in WvConfEmu ***\n");
245 for (i.rewind(); i.next(); )
247 fprintf(stderr,
" - [%s]%s (%p)\n", i->section.cstr(),
248 i->key.cstr(), i->cookie);
257 void WvConfEmu::zap()
263 bool WvConfEmu::isclean()
const
265 return isok() && !dirty;
269 bool WvConfEmu::isok()
const
275 void WvConfEmu::load_file(WvStringParm filename)
280 new_uniconf.copy(uniconf,
true);
285 void WvConfEmu::save(WvStringParm filename,
int _create_mode)
289 uniconf.
copy(tmp_uniconf,
true);
291 tmp_uniconf.commit();
295 void WvConfEmu::save()
301 void WvConfEmu::flush()
315 if (!section && uniconf[sect].exists())
318 sections.add(section,
true);
325 void WvConfEmu::add_callback(WvConfCallback callback,
void *userdata,
326 WvStringParm section, WvStringParm key,
333 for (i.rewind(); i.next(); )
335 if (i->cookie == cookie
336 && i->section == section
341 #ifdef DEBUG_DEL_CALLBACK
343 int count = backtrace(trace,
sizeof(trace)/
sizeof(trace[0]));
344 char** tracedump = backtrace_symbols(trace, count);
345 fprintf(stderr,
"TRACE:add:%s:%s:%p", section.cstr(), key.cstr(), cookie);
346 for (
int i = 0; i < count; ++i)
347 fprintf(stderr,
":%s", tracedump[i]);
348 fprintf(stderr,
"\n");
352 callbacks.
append(
new CallbackInfo(callback, userdata, section, key,
358 void WvConfEmu::del_callback(WvStringParm section, WvStringParm key,
void *cookie)
364 for (i.rewind(); i.next(); )
366 if (i->cookie == cookie
367 && i->section == section
370 #ifdef DEBUG_DEL_CALLBACK
371 fprintf(stderr,
"TRACE:del:%s:%s:%p\n", section.cstr(), key.cstr(), cookie);
379 void WvConfEmu::add_setbool(
bool *b, WvStringParm _section, WvStringParm _key)
381 add_callback(do_setbool, b, _section, _key, b);
385 void WvConfEmu::del_setbool(
bool *b, WvStringParm _section, WvStringParm _key)
387 del_callback(_section, _key, b);
391 void WvConfEmu::add_addname(
WvStringList *list, WvStringParm sect, WvStringParm ent)
393 add_callback(do_addname, list, sect, ent, list);
398 WvStringParm sect, WvStringParm ent)
400 del_callback(sect, ent, list);
406 char *section, *entry, *value;
407 parse_error = parse_wvconf_request(wvconfstr.
edit(),
408 section, entry, value);
413 return get(section, entry, value);
417 int WvConfEmu::getint(WvStringParm section, WvStringParm entry,
int def_val)
419 if (!section || !entry)
422 return uniconf[section][entry].
getmeint(def_val);
426 const char *WvConfEmu::get(WvStringParm section, WvStringParm entry,
429 if (!section || !entry)
432 WvString s(uniconf[section][entry].getme(def_val));
436 if (!sp) values.add(sp =
new WvString(s),
true);
440 int WvConfEmu::fuzzy_getint(
WvStringList §, WvStringParm entry,
444 return check_for_bool_string(fuzzy_get(sect, entry, def_str));
448 const char *WvConfEmu::fuzzy_get(
WvStringList §, WvStringParm entry,
451 WvStringList::Iter i(sect);
455 for (i.rewind(); i.next(); )
458 s && !cache[s->name];
459 s = (*s)[
"Inherits"] ? (*this)[(*s)[
"Inherits"]->value] : NULL)
461 const char *ret = s->get(entry);
463 cache.add(&s->name,
false);
470 void WvConfEmu::setraw(
WvString wvconfstr,
const char *&_value,
473 char *section, *entry, *value;
474 parse_error = parse_wvconf_request(wvconfstr.
edit(),
475 section, entry, value);
478 set(section, entry, value);
479 _value =
get(section, entry, value);
486 void WvConfEmu::setint(WvStringParm section, WvStringParm entry,
int value)
489 uniconf[section][entry].
setmeint(value);
493 void WvConfEmu::set(WvStringParm section, WvStringParm entry,
498 if (value && value[0] != 0)
499 uniconf[section][entry].
setme(value);
501 uniconf[section][entry].
setme(WvString::null);
507 void WvConfEmu::maybesetint(WvStringParm section, WvStringParm entry,
510 if (!!entry && !
get(section, entry, NULL))
511 setint(section, entry, value);
515 void WvConfEmu::maybeset(WvStringParm section, WvStringParm entry,
518 if (!!entry &&
get(section, entry, 0) == 0)
519 set(section, entry, value);
523 void WvConfEmu::delete_section(WvStringParm section)
525 uniconf[section].
remove();
530 int WvConfEmu::check_for_bool_string(
const char *s)
532 if (strcasecmp(s,
"off") == 0
533 || strcasecmp(s,
"false") == 0
534 || strncasecmp(s,
"no", 2) == 0)
537 if (strcasecmp(s,
"on") == 0
538 || strcasecmp(s,
"true") == 0
539 || strcasecmp(s,
"yes") == 0)
547 void WvConfEmu::Iter::rewind()
554 WvLink *WvConfEmu::Iter::next()
557 while (link.data == NULL && iter.next())
559 link.data =
static_cast<void*
>(conf[iter->key()]);
571 return conf[iter->key()];