Fix several warnings that appear in gcc 4.3.2.
[wvstreams.git] / uniconf / uniconfgen.cc
blob1d94eec9a8b0e330a2569b9c5f0c65ff5cae8f06
1 /*
2 * Worldvisions Weaver Software:
3 * Copyright (C) 2002 Net Integration Technologies, Inc.
4 *
5 * An abstract data container that backs a UniConf tree.
6 */
7 #include "uniconfgen.h"
8 #include "strutils.h"
10 // FIXME: interfaces (IUniConfGen) shouldn't have implementations!
11 IUniConfGen::~IUniConfGen()
15 UUID_MAP_BEGIN(UniConfGen)
16 UUID_MAP_ENTRY(IObject)
17 UUID_MAP_ENTRY(IUniConfGen)
18 UUID_MAP_END
20 UniConfGen::UniConfGen()
22 hold_nesting = 0;
26 UniConfGen::~UniConfGen()
28 assert(cblist.isempty());
32 void UniConfGen::hold_delta()
34 hold_nesting++;
38 void UniConfGen::unhold_delta()
40 assert(hold_nesting > 0);
41 if (hold_nesting == 1)
42 flush_delta();
43 hold_nesting--;
47 void UniConfGen::clear_delta()
49 deltas.zap();
53 void UniConfGen::flush_delta()
55 UniConfPairList::Iter it(deltas);
56 for (;;)
58 it.rewind();
59 if (! it.next())
60 break;
62 UniConfKey key((*it).key());
63 WvString value((*it).value());
65 it.xunlink();
66 dispatch_delta(key, value);
71 void UniConfGen::dispatch_delta(const UniConfKey &key, WvStringParm value)
73 cblist(key, value);
77 void UniConfGen::delta(const UniConfKey &key, WvStringParm value)
79 if (hold_nesting == 0)
81 // not nested, dispatch immediately
82 dispatch_delta(key, value);
84 else
86 hold_delta();
87 deltas.add(new UniConfPair(key, value), true);
88 unhold_delta();
93 void UniConfGen::setv_naive(const UniConfPairList &pairs)
95 UniConfPairList::Iter pair(pairs);
96 for (pair.rewind(); pair.next(); )
97 set(pair->key(), pair->value());
101 bool UniConfGen::haschildren(const UniConfKey &key)
103 bool children = false;
105 hold_delta();
107 Iter *it = iterator(key);
108 if (it)
110 it->rewind();
111 if (it->next()) children = true;
112 delete it;
115 unhold_delta();
116 return children;
120 bool UniConfGen::exists(const UniConfKey &key)
122 return !get(key).isnull();
126 int UniConfGen::str2int(WvStringParm value, int defvalue) const
128 // also recognize bool strings as integers
129 const char *strs[] = {
130 "true", "yes", "on", "enabled",
131 "false", "no", "off", "disabled"
133 const size_t numtruestrs = 4;
135 if (!value.isnull())
137 // try to recognize an integer
138 char *end;
139 int num = strtol(value.cstr(), &end, 0);
140 if (end != value.cstr())
141 return num; // was a valid integer
143 // try to recognize a special string
144 for (size_t i = 0; i < sizeof(strs) / sizeof(const char*); ++i)
145 if (strcasecmp(value, strs[i]) == 0)
146 return i < numtruestrs;
148 return defvalue;
152 bool UniConfGen::isok()
154 return true;
158 void UniConfGen::add_callback(void *cookie,
159 const UniConfGenCallback &callback)
161 cblist.add(callback, cookie);
165 void UniConfGen::del_callback(void *cookie)
167 cblist.del(cookie);
172 class _UniConfGenRecursiveIter : public IUniConfGen::Iter
174 WvList<IUniConfGen::Iter> itlist;
175 IUniConfGen *gen;
176 UniConfKey top, current;
177 bool sub_next;
179 public:
180 _UniConfGenRecursiveIter(IUniConfGen *_gen, const UniConfKey &_top)
181 : top(_top)
183 gen = _gen;
184 sub_next = false;
187 virtual ~_UniConfGenRecursiveIter() { }
189 virtual void rewind()
191 current = "";
192 sub_next = false;
193 itlist.zap();
195 Iter *subi = gen->iterator(top);
196 if (subi)
198 subi->rewind();
199 itlist.prepend(subi, true);
203 virtual bool next()
205 //assert(!itlist.isempty()); // trying to seek past the end is illegal!
207 if (sub_next)
209 sub_next = false;
211 UniConfKey subkey(itlist.first()->key());
212 UniConfKey newkey(current, subkey);
213 //fprintf(stderr, "subiter: '%s'\n", newkey.cstr());
214 Iter *newsub = gen->iterator(UniConfKey(top, newkey));
215 if (newsub)
217 current.append(subkey);
218 //fprintf(stderr, "current is now: '%s'\n", current.cstr());
219 newsub->rewind();
220 itlist.prepend(newsub, true);
224 WvList<IUniConfGen::Iter>::Iter i(itlist);
225 for (i.rewind(); i.next(); )
227 if (i->next()) // NOTE: not the same as i.next()
229 // set up so next time, we go into its subtree
230 sub_next = true;
231 return true;
234 // otherwise, this iterator is empty; move up the tree
235 current = current.removelast();
236 //fprintf(stderr, "current is now: '%s'\n", current.cstr());
237 i.xunlink();
240 // all done!
241 return false;
244 virtual UniConfKey key() const
246 //fprintf(stderr, "current is now: '%s'\n", current.cstr());
247 if (!itlist.isempty())
248 return UniConfKey(current, itlist.first()->key());
249 else
250 return current;
253 virtual WvString value() const
255 return gen->get(UniConfKey(top, key()));
260 UniConfGen::Iter *UniConfGen::recursiveiterator(const UniConfKey &key)
262 return new _UniConfGenRecursiveIter(this, key);