9#include "wvstringtable.h"
14#ifdef DEBUG_DEL_CALLBACK
34static 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,
'=');
68static void do_setbool(
void *userdata,
72 bool* b =
static_cast<bool*
>(userdata);
78static void do_addname(
void *userdata,
91 if (uniconf[s].exists())
96 entries.add(entry,
true);
99 entry->value = uniconf[s].
getme();
108const 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);
127 uniconf[entry].
setme(value);
129 uniconf[entry].
setme(WvString::null);
136 uniconf[entry].
setme(value);
140bool WvConfigSectionEmu::isempty()
const
146WvConfigSectionEmu::Iter::~Iter()
151void WvConfigSectionEmu::Iter::rewind()
154 link.data = entry = NULL;
158WvLink *WvConfigSectionEmu::Iter::next()
170 entry = sect[iter->fullkey(sect.uniconf)];
171 link.data =
static_cast<void*
>(entry);
181WvLink *WvConfigSectionEmu::Iter::cur()
193void *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);
221WvConfEmu::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),
231WvConfEmu::~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);
263bool WvConfEmu::isclean()
const
265 return isok() && !dirty;
269bool WvConfEmu::isok()
const
280 new_uniconf.copy(uniconf,
true);
285void WvConfEmu::save(
WvStringParm filename,
int _create_mode)
289 uniconf.
copy(tmp_uniconf,
true);
291 tmp_uniconf.commit();
295void WvConfEmu::save()
301void WvConfEmu::flush()
315 if (!section && uniconf[sect].exists())
318 sections.add(section,
true);
325void WvConfEmu::add_callback(WvConfCallback callback,
void *userdata,
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,
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);
381 add_callback(do_setbool, b, _section, _key, b);
387 del_callback(_section, _key, b);
393 add_callback(do_addname, list, sect, ent, list);
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);
419 if (!section || !entry)
422 return uniconf[section][entry].
getmeint(def_val);
429 if (!section || !entry)
432 WvString s(uniconf[section][entry].getme(def_val));
436 if (!sp) values.add(sp =
new WvString(s),
true);
444 return check_for_bool_string(fuzzy_get(sect, entry, def_str));
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);
470void 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);
489 uniconf[section][entry].
setmeint(value);
498 if (value && value[0] != 0)
499 uniconf[section][entry].
setme(value);
501 uniconf[section][entry].
setme(WvString::null);
510 if (!!entry && !get(section, entry, NULL))
511 setint(section, entry, value);
518 if (!!entry && get(section, entry, 0) == 0)
519 set(section, entry, value);
525 uniconf[section].
remove();
530int 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)
547void WvConfEmu::Iter::rewind()
554WvLink *WvConfEmu::Iter::next()
557 while (link.data == NULL && iter.next())
559 link.data =
static_cast<void*
>(conf[iter->key()]);
571 return conf[iter->key()];
Represents a UniConf key which is a path in a hierarchy structured much like the traditional Unix fil...
UniConfKey removefirst(int n=1) const
Returns the path formed by removing the first n segments of this path.
UniConfKey first(int n=1) const
Returns the path formed by the n first segments of this path.
Represents the root of a hierarhical registry consisting of pairs of UniConfKeys and associated strin...
UniConf instances function as handles to subtrees of a UniConf tree and expose a high-level interface...
void commit() const
Commits information about this key recursively.
void add_callback(void *cookie, const UniConfCallback &callback, bool recurse=true) const
Requests notification when any of the keys covered by the recursive depth specification change by inv...
void remove() const
Removes this key and all of its children from the registry.
int getmeint(int defvalue=0) const
Fetches the integer value for this key from the registry.
bool haschildren() const
Returns true if this key has children.
void setme(WvStringParm value) const
Stores a string value for this key into the registry.
bool isnull() const
Returns true if the handle is invalid (NULL).
void del_callback(void *cookie, bool recurse=true) const
Cancels notification requested using add_callback().
void copy(const UniConf &dst, bool force) const
Equivalent to "cp -r" in a standard unix filesystem.
void setmeint(int value) const
Stores an integer value for this key into the registry.
WvString getme(WvStringParm defvalue=WvString::null) const
Fetches the string value for this key from the registry.
Loads and saves ".ini"-style files similar to those used by Windows, but adapted to represent keys an...
A WvFastString acts exactly like a WvString, but can take (const char *) strings without needing to a...
const char * cstr() const
return a (const char *) for this string.
WvLink is one element of a WvList<T>.
bool isempty() const
Quickly determines if the list is empty.
A linked list container class.
void append(T *data, bool autofree, const char *id=NULL)
Appends the element to the end of the list.
This is a WvList of WvStrings, and is a really handy way to parse strings.
WvString is an implementation of a simple and efficient printable-string class.
char * edit()
make the string editable, and return a non-const (char*)
char * trim_string(char *string)
Trims whitespace from the beginning and end of the character string, including carriage return / line...