1 | //
|
---|
2 | // keyval.h
|
---|
3 | //
|
---|
4 | // Copyright (C) 1996 Limit Point Systems, Inc.
|
---|
5 | //
|
---|
6 | // Author: Curtis Janssen <cljanss@limitpt.com>
|
---|
7 | // Maintainer: LPS
|
---|
8 | //
|
---|
9 | // This file is part of the SC Toolkit.
|
---|
10 | //
|
---|
11 | // The SC Toolkit is free software; you can redistribute it and/or modify
|
---|
12 | // it under the terms of the GNU Library General Public License as published by
|
---|
13 | // the Free Software Foundation; either version 2, or (at your option)
|
---|
14 | // any later version.
|
---|
15 | //
|
---|
16 | // The SC Toolkit is distributed in the hope that it will be useful,
|
---|
17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
19 | // GNU Library General Public License for more details.
|
---|
20 | //
|
---|
21 | // You should have received a copy of the GNU Library General Public License
|
---|
22 | // along with the SC Toolkit; see the file COPYING.LIB. If not, write to
|
---|
23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
24 | //
|
---|
25 | // The U.S. Government is granted a limited license as per AL 91-7.
|
---|
26 | //
|
---|
27 |
|
---|
28 | #ifndef _util_keyval_keyval_h
|
---|
29 | #define _util_keyval_keyval_h
|
---|
30 | #ifdef __GNUG__
|
---|
31 | #pragma interface
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #include <iostream>
|
---|
35 | #include <string>
|
---|
36 | #include <map>
|
---|
37 |
|
---|
38 | #include <string.h>
|
---|
39 | #include <stdlib.h>
|
---|
40 | #include <stdarg.h>
|
---|
41 |
|
---|
42 | #include <util/class/class.h>
|
---|
43 | #include <util/keyval/keyvalval.h>
|
---|
44 |
|
---|
45 | namespace sc {
|
---|
46 |
|
---|
47 | /**
|
---|
48 | The KeyVal class is designed to simplify the process of allowing
|
---|
49 | a user to specify keyword/value associations to a C++ program. A
|
---|
50 | flexible input style and ease of use for the programmer is achieved with
|
---|
51 | this method. Keywords are represented by null terminated character arrays.
|
---|
52 | The keywords are organized hierarchially, in a manner similar to the way
|
---|
53 | that many file systems are organized. One character is special,
|
---|
54 | ":", which is used to separate the various hierarchial labels,
|
---|
55 | which are referred to as "segments", in the keyword.
|
---|
56 |
|
---|
57 | A convention for specifying arrays is provided by KeyVal. Each
|
---|
58 | index of the array is given by appending a segment containing the
|
---|
59 | character representation of the index. Thus, "array:3:4" would be
|
---|
60 | a the keyword corresponding to fourth row and fifth column of
|
---|
61 | "array", since indexing starts at zero.
|
---|
62 |
|
---|
63 | To allow the KeyVal class to have associations that can represent
|
---|
64 | data for classes, the keyword can be associated with a class as well as
|
---|
65 | a value. This permits polymorphic data to be unambiguously represented
|
---|
66 | by keyword/value associations. Most use of KeyVal need not be
|
---|
67 | concerned with this.
|
---|
68 | */
|
---|
69 | class KeyVal: public RefCount {
|
---|
70 | // these classes need to directly access the key_value member
|
---|
71 | friend class AggregateKeyVal;
|
---|
72 | friend class PrefixKeyVal;
|
---|
73 | public:
|
---|
74 | enum {MaxKeywordLength = 256};
|
---|
75 | enum KeyValError { OK, HasNoValue, WrongType,
|
---|
76 | UnknownKeyword, OperationFailed };
|
---|
77 | private:
|
---|
78 | KeyValError errcod;
|
---|
79 | // do not allow a copy constructor or assignment
|
---|
80 | KeyVal(const KeyVal&);
|
---|
81 | void operator=(const KeyVal&);
|
---|
82 | protected:
|
---|
83 | int verbose_;
|
---|
84 |
|
---|
85 | KeyVal();
|
---|
86 |
|
---|
87 | /// Set the current error condition.
|
---|
88 | void seterror(KeyValError err);
|
---|
89 | /// Set the current error condition.
|
---|
90 | void seterror(KeyValValue::KeyValValueError err);
|
---|
91 |
|
---|
92 | /// Ultimately called by exists.
|
---|
93 | virtual int key_exists(const char*) = 0;
|
---|
94 | /// Ultimately called by count.
|
---|
95 | virtual int key_count(const char* =0);
|
---|
96 | /// Ultimately called by value.
|
---|
97 | virtual Ref<KeyValValue> key_value(const char*,
|
---|
98 | const KeyValValue& def) = 0;
|
---|
99 | /// Ultimately called by booleanvalue.
|
---|
100 | virtual int key_booleanvalue(const char*,const KeyValValue& def);
|
---|
101 | /// Ultimately called by doublevalue.
|
---|
102 | virtual double key_doublevalue(const char* key,const KeyValValue& def);
|
---|
103 | /// Ultimately called by floatvalue.
|
---|
104 | virtual float key_floatvalue(const char* key,const KeyValValue& def);
|
---|
105 | /// Ultimately called by charvalue.
|
---|
106 | virtual char key_charvalue(const char* key,const KeyValValue& def);
|
---|
107 | /// Ultimately called by intvalue.
|
---|
108 | virtual int key_intvalue(const char* key,const KeyValValue& def);
|
---|
109 | /// Ultimately called by sizevalue.
|
---|
110 | virtual size_t key_sizevalue(const char* key,const KeyValValue& def);
|
---|
111 | /// Ultimately called by pcharvalue.
|
---|
112 | virtual char* key_pcharvalue(const char* key,const KeyValValue& def);
|
---|
113 | /// Ultimately called by stringvalue.
|
---|
114 | virtual std::string key_stringvalue(const char* key,
|
---|
115 | const KeyValValue& def);
|
---|
116 | /// Ultimately called by describedclassvalue.
|
---|
117 | virtual Ref<DescribedClass> key_describedclassvalue(const char* key,
|
---|
118 | const KeyValValue& def);
|
---|
119 |
|
---|
120 | public:
|
---|
121 | virtual ~KeyVal();
|
---|
122 |
|
---|
123 | // For nonindexed things. If a subclass defines one of these,
|
---|
124 | // then the overloaded functions will be hidden. The key_... functions
|
---|
125 | // should be overridden instead.
|
---|
126 |
|
---|
127 | /** This takes as its only argument a keyword.
|
---|
128 | Returns 1 if the keyword has a value and 0 otherwise. */
|
---|
129 | int exists(const char*);
|
---|
130 | /** If the value of a keyword is an array, then return its length.
|
---|
131 | If no arguments are given then the top level will be checked to
|
---|
132 | see if it is an array and, if so, the number of elements will be
|
---|
133 | counted. */
|
---|
134 | int count(const char* =0);
|
---|
135 | /// Return the value associated with the keyword.
|
---|
136 | Ref<KeyValValue> value(const char* = 0,
|
---|
137 | const KeyValValue& def=KeyValValue());
|
---|
138 | /// Returns the boolean value (0 = false, 1 = true) of key.
|
---|
139 | int booleanvalue(const char* key = 0,
|
---|
140 | const KeyValValue& def=KeyValValueboolean());
|
---|
141 | /// Returns the double value of key.
|
---|
142 | double doublevalue(const char* key = 0,
|
---|
143 | const KeyValValue& def=KeyValValuedouble());
|
---|
144 | /// Returns the float value of key.
|
---|
145 | float floatvalue(const char* key = 0,
|
---|
146 | const KeyValValue& def=KeyValValuefloat());
|
---|
147 | /// Returns the char value of key.
|
---|
148 | char charvalue(const char* key = 0,
|
---|
149 | const KeyValValue& def=KeyValValuechar());
|
---|
150 | /// Returns the int value of key.
|
---|
151 | int intvalue(const char* key = 0,
|
---|
152 | const KeyValValue& def=KeyValValueint());
|
---|
153 | /// Returns the size_t value of key.
|
---|
154 | size_t sizevalue(const char* key = 0,
|
---|
155 | const KeyValValue& def=KeyValValuesize());
|
---|
156 | /** Returns a copy of the string representation of the key's
|
---|
157 | value. Storage for the copy is obtained with new. */
|
---|
158 | char* pcharvalue(const char* key = 0,
|
---|
159 | const KeyValValue& def=KeyValValuepchar());
|
---|
160 | /** Returns a string representation of the key's value. */
|
---|
161 | std::string stringvalue(const char* key = 0,
|
---|
162 | const KeyValValue& def=KeyValValuestring());
|
---|
163 | /// Returns a reference to an object of type DescribedClass.
|
---|
164 | Ref<DescribedClass> describedclassvalue(const char* key = 0,
|
---|
165 | const KeyValValue& def=KeyValValueRefDescribedClass());
|
---|
166 |
|
---|
167 | /** @name Reading Vectors.
|
---|
168 | These members correspond to the above members, but take
|
---|
169 | an additional integer argument, i, which is a vector index.
|
---|
170 | This is equivalent to getting a value for a keyword named
|
---|
171 | "<i>key</i>:<i>i</i>". The routines that do not take
|
---|
172 | key arguments get the value for the keyword named "<i>i</i>".
|
---|
173 | */
|
---|
174 | //@{
|
---|
175 | int exists(const char* key,int i);
|
---|
176 | int count(const char* key,int i);
|
---|
177 | int booleanvalue(const char* key,int i,
|
---|
178 | const KeyValValue& def=KeyValValueboolean());
|
---|
179 | double doublevalue(const char* key,int i,
|
---|
180 | const KeyValValue& def=KeyValValuedouble());
|
---|
181 | float floatvalue(const char* key,int i,
|
---|
182 | const KeyValValue& def=KeyValValuefloat());
|
---|
183 | char charvalue(const char* key,int i,
|
---|
184 | const KeyValValue& def=KeyValValuechar());
|
---|
185 | int intvalue(const char* key,int i,
|
---|
186 | const KeyValValue& def=KeyValValueint());
|
---|
187 | size_t sizevalue(const char* key,int i,
|
---|
188 | const KeyValValue& def=KeyValValuesize());
|
---|
189 | char* pcharvalue(const char* key,int i,
|
---|
190 | const KeyValValue& def=KeyValValuepchar());
|
---|
191 | std::string stringvalue(const char* key,int i,
|
---|
192 | const KeyValValue& def=KeyValValuestring());
|
---|
193 | Ref<DescribedClass> describedclassvalue(const char* key,int,
|
---|
194 | const KeyValValue& def=KeyValValueRefDescribedClass());
|
---|
195 |
|
---|
196 | int exists(int i);
|
---|
197 | int count(int i);
|
---|
198 | int booleanvalue(int i,
|
---|
199 | const KeyValValue& def=KeyValValueboolean());
|
---|
200 | double doublevalue(int i,
|
---|
201 | const KeyValValue& def=KeyValValuedouble());
|
---|
202 | float floatvalue(int i,
|
---|
203 | const KeyValValue& def=KeyValValuefloat());
|
---|
204 | char charvalue(int i,
|
---|
205 | const KeyValValue& def=KeyValValuechar());
|
---|
206 | int intvalue(int i,
|
---|
207 | const KeyValValue& def=KeyValValueint());
|
---|
208 | size_t sizevalue(int i,
|
---|
209 | const KeyValValue& def=KeyValValuesize());
|
---|
210 | char* pcharvalue(int i,
|
---|
211 | const KeyValValue& def=KeyValValuepchar());
|
---|
212 | std::string stringvalue(int i,
|
---|
213 | const KeyValValue& def=KeyValValuestring());
|
---|
214 | Ref<DescribedClass> describedclassvalue(int i,
|
---|
215 | const KeyValValue& def=KeyValValueRefDescribedClass());
|
---|
216 | //@}
|
---|
217 |
|
---|
218 | /** @name Reading 2D Arrays.
|
---|
219 | These members correspond to the above members, but take additional
|
---|
220 | integer arguments, i and j, which is an array index. This is
|
---|
221 | equivalent to getting a value for a keyword named
|
---|
222 | "<i>key</i>:<i>i</i>:<i>j</i>". The routines that do not take key
|
---|
223 | arguments get the value for the keyword named "<i>i</i>:<i>j</i>". */
|
---|
224 | //@{
|
---|
225 | int exists(const char*,int,int);
|
---|
226 | int count(const char*,int,int);
|
---|
227 | int booleanvalue(const char*,int,int,
|
---|
228 | const KeyValValue& def=KeyValValueboolean());
|
---|
229 | double doublevalue(const char* key,int,int,
|
---|
230 | const KeyValValue& def=KeyValValuedouble());
|
---|
231 | float floatvalue(const char* key,int,int,
|
---|
232 | const KeyValValue& def=KeyValValuefloat());
|
---|
233 | char charvalue(const char* key,int,int,
|
---|
234 | const KeyValValue& def=KeyValValuechar());
|
---|
235 | int intvalue(const char* key,int,int,
|
---|
236 | const KeyValValue& def=KeyValValueint());
|
---|
237 | size_t sizevalue(const char* key,int,int,
|
---|
238 | const KeyValValue& def=KeyValValuesize());
|
---|
239 | char* pcharvalue(const char* key,int,int,
|
---|
240 | const KeyValValue& def=KeyValValuepchar());
|
---|
241 | std::string stringvalue(const char* key,int,int,
|
---|
242 | const KeyValValue& def=KeyValValuestring());
|
---|
243 | Ref<DescribedClass> describedclassvalue(const char* key,int,int,
|
---|
244 | const KeyValValue& def=KeyValValueRefDescribedClass());
|
---|
245 |
|
---|
246 | int exists(int i,int j);
|
---|
247 | int count(int i,int j);
|
---|
248 | int booleanvalue(int i,int j,
|
---|
249 | const KeyValValue& def=KeyValValueboolean());
|
---|
250 | double doublevalue(int i,int j,
|
---|
251 | const KeyValValue& def=KeyValValuedouble());
|
---|
252 | float floatvalue(int i,int j,
|
---|
253 | const KeyValValue& def=KeyValValuefloat());
|
---|
254 | char charvalue(int i,int j,
|
---|
255 | const KeyValValue& def=KeyValValuechar());
|
---|
256 | int intvalue(int i,int j,
|
---|
257 | const KeyValValue& def=KeyValValueint());
|
---|
258 | size_t sizevalue(int i,int j,
|
---|
259 | const KeyValValue& def=KeyValValuesize());
|
---|
260 | char* pcharvalue(int i,int j,
|
---|
261 | const KeyValValue& def=KeyValValuepchar());
|
---|
262 | std::string stringvalue(int i,int j,
|
---|
263 | const KeyValValue& def=KeyValValuestring());
|
---|
264 | Ref<DescribedClass> describedclassvalue(int i,int j,
|
---|
265 | const KeyValValue& def=KeyValValueRefDescribedClass());
|
---|
266 | //@}
|
---|
267 |
|
---|
268 | /** @name Reading 3D Arrays.
|
---|
269 | These members correspond to the above members, but can be used
|
---|
270 | to read in arrays with more than two dimensions. The nindex
|
---|
271 | argument is the number of indices in the array. It is followed
|
---|
272 | by an int giving the value of each index. */
|
---|
273 | //@{
|
---|
274 | int Va_exists(const char* key,int nindex,...);
|
---|
275 | int Va_count(const char* key,int nindex,...);
|
---|
276 | int Va_booleanvalue(const char* key,int nindex,...);
|
---|
277 | double Va_doublevalue(const char* key,int nindex,...);
|
---|
278 | float Va_floatvalue(const char* key,int nindex,...);
|
---|
279 | char Va_charvalue(const char* key,int nindex,...);
|
---|
280 | int Va_intvalue(const char* key,int nindex,...);
|
---|
281 | size_t Va_sizevalue(const char* key,int nindex,...);
|
---|
282 | char* Va_pcharvalue(const char* key,int nindex,...);
|
---|
283 | std::string Va_stringvalue(const char* key,int nindex,...);
|
---|
284 | Ref<DescribedClass> Va_describedclassvalue(const char* key,int nindex,...);
|
---|
285 | //@}
|
---|
286 |
|
---|
287 | /// Return the current error condition.
|
---|
288 | KeyValError error();
|
---|
289 | /// Return a textual representation of err.
|
---|
290 | const char* errormsg(KeyValError err);
|
---|
291 | /// Return a textual representation of the current error.
|
---|
292 | const char* errormsg();
|
---|
293 | /// Write a message to fp describing the error.
|
---|
294 | virtual void errortrace(std::ostream&fp=ExEnv::err0());
|
---|
295 | /// Write a message to fp describing the error.
|
---|
296 | virtual void dump(std::ostream&fp=ExEnv::err0());
|
---|
297 |
|
---|
298 | /// Print keywords that were never looked at, if possible.
|
---|
299 | virtual void print_unseen(std::ostream&fp=ExEnv::out0());
|
---|
300 | /** Return 1 if there were unseen keywords, 0 if there are
|
---|
301 | none, or -1 this keyval doesn't keep track of unseen
|
---|
302 | keywords. */
|
---|
303 | virtual int have_unseen();
|
---|
304 |
|
---|
305 | /// Control printing of assignments.
|
---|
306 | void verbose(int v) { verbose_ = v; }
|
---|
307 | /// Returns nonzero if assignments are printed.
|
---|
308 | int verbose() const { return verbose_; }
|
---|
309 | };
|
---|
310 |
|
---|
311 |
|
---|
312 |
|
---|
313 | /** This class allows keyval associations to be set up by the program,
|
---|
314 | rather than determined by an external file. */
|
---|
315 | class AssignedKeyVal: public KeyVal {
|
---|
316 | private:
|
---|
317 | std::map<std::string,Ref<KeyValValue> > _map;
|
---|
318 | // do not allow a copy constructor or assignment
|
---|
319 | AssignedKeyVal(const AssignedKeyVal&);
|
---|
320 | void operator=(const AssignedKeyVal&);
|
---|
321 | protected:
|
---|
322 | int key_exists(const char*);
|
---|
323 | Ref<KeyValValue> key_value(const char*,
|
---|
324 | const KeyValValue& def);
|
---|
325 | public:
|
---|
326 | AssignedKeyVal();
|
---|
327 | ~AssignedKeyVal();
|
---|
328 |
|
---|
329 | /** @name Assignments.
|
---|
330 | Each of this routines assigns key to val. */
|
---|
331 | //@{
|
---|
332 | void assign(const char* key, const Ref<KeyValValue>& val);
|
---|
333 | void assign(const char* key, double val);
|
---|
334 | void assignboolean(const char* key, int val);
|
---|
335 | void assign(const char* key, float val);
|
---|
336 | void assign(const char* key, char val);
|
---|
337 | void assign(const char* key, int val);
|
---|
338 | void assign(const char* key, const char* val);
|
---|
339 | void assign(const char* key, const Ref<DescribedClass>& val);
|
---|
340 | //@}
|
---|
341 |
|
---|
342 | /// Erase all of the stored assignments.
|
---|
343 | void clear();
|
---|
344 | };
|
---|
345 |
|
---|
346 |
|
---|
347 |
|
---|
348 | /** StringKeyVal is a base class for KeyVal implementations
|
---|
349 | that store all values in a string format. These are
|
---|
350 | converted to other data types through KeyValValue.
|
---|
351 | */
|
---|
352 | class StringKeyVal: public KeyVal {
|
---|
353 | private:
|
---|
354 | // once a described class is found it is kept here so
|
---|
355 | // multiple references to it return the same instance
|
---|
356 | std::map<std::string,Ref<KeyValValue> > _map;
|
---|
357 | // do not allow a copy constructor or assignment
|
---|
358 | StringKeyVal(const StringKeyVal&);
|
---|
359 | void operator=(const StringKeyVal&);
|
---|
360 | protected:
|
---|
361 | StringKeyVal();
|
---|
362 | int key_exists(const char*);
|
---|
363 | Ref<KeyValValue> key_value(const char*,
|
---|
364 | const KeyValValue& def);
|
---|
365 | public:
|
---|
366 | virtual ~StringKeyVal();
|
---|
367 | /// Returns the string representation of the value assigned to key.
|
---|
368 | virtual const char* stringrep(const char *key) = 0;
|
---|
369 | /** Returns the name of the exact class of the object at the keyword.
|
---|
370 | If no classname is assigned then 0 is returned. */
|
---|
371 | virtual const char* classname(const char*);
|
---|
372 | /** Returns a string which is the actual keyword if some sort
|
---|
373 | of variable substitution takes place (needed to make multiple
|
---|
374 | references to the same object work in input files). */
|
---|
375 | virtual const char* truekeyword(const char*);
|
---|
376 |
|
---|
377 | /** @name Debugging.
|
---|
378 | See the parent class documentation for descriptions of these functions.
|
---|
379 | */
|
---|
380 | //@{
|
---|
381 | virtual void errortrace(std::ostream&fp=ExEnv::err0());
|
---|
382 | virtual void dump(std::ostream&fp=ExEnv::err0());
|
---|
383 | //@}
|
---|
384 | };
|
---|
385 |
|
---|
386 | /** This takes several KeyVal objects and makes them look like
|
---|
387 | one KeyVal object. When a key is sought first KeyVal, then
|
---|
388 | the next, and so on is searched until the keyword is found.
|
---|
389 | */
|
---|
390 | class AggregateKeyVal : public KeyVal {
|
---|
391 | private:
|
---|
392 | enum { MaxKeyVal = 4 };
|
---|
393 | Ref<KeyVal> kv[MaxKeyVal];
|
---|
394 | Ref<KeyVal> getkeyval(const char*key);
|
---|
395 | // do not allow a copy constructor or assignment
|
---|
396 | AggregateKeyVal(const AggregateKeyVal&);
|
---|
397 | void operator=(const AggregateKeyVal&);
|
---|
398 | protected:
|
---|
399 | int key_exists(const char*);
|
---|
400 | Ref<KeyValValue> key_value(const char*,
|
---|
401 | const KeyValValue& def);
|
---|
402 | public:
|
---|
403 | /** @name Constructors.
|
---|
404 | These contructors create an AggregateKeyVal that is formed from
|
---|
405 | several other KeyVal objects. The search order is keyval1,
|
---|
406 | keyval2, and so on. All KeyVal objects including and after the
|
---|
407 | first null KeyVal will be ignored.
|
---|
408 | */
|
---|
409 | //@{
|
---|
410 | AggregateKeyVal(const Ref<KeyVal>& keyval1);
|
---|
411 | AggregateKeyVal(const Ref<KeyVal>& keyval1,const Ref<KeyVal>& keyval2);
|
---|
412 | AggregateKeyVal(const Ref<KeyVal>& keyval1,const Ref<KeyVal>& keyval2,
|
---|
413 | const Ref<KeyVal>& keyval3);
|
---|
414 | AggregateKeyVal(const Ref<KeyVal>& keyval1,const Ref<KeyVal>& keyval2,
|
---|
415 | const Ref<KeyVal>& keyval3, const Ref<KeyVal>& keyval4);
|
---|
416 | //@}
|
---|
417 | ~AggregateKeyVal();
|
---|
418 | void errortrace(std::ostream&fp=ExEnv::err0());
|
---|
419 | void dump(std::ostream&fp=ExEnv::err0());
|
---|
420 | };
|
---|
421 |
|
---|
422 | /** PrefixKeyVal is a KeyVal that searches a different KeyVal using
|
---|
423 | modified keys. This is convenient for reading keys grouped together
|
---|
424 | with a common prefix. Consider the following code:
|
---|
425 | <pre>
|
---|
426 | sc::Ref<sc::KeyVal> keyval = new sc::PrefixKeyVal("A",original_keyval);
|
---|
427 | int r = keyval->intvalue("x");
|
---|
428 | </pre>
|
---|
429 | This code will assign to r the value associated with "x" in keyval.
|
---|
430 | keyval will search for "x" by searching for "A::x" in original_keyval.
|
---|
431 |
|
---|
432 | This class is important for implementing constructors that take
|
---|
433 | KeyVal arguments. When an object is being constructed from a KeyVal,
|
---|
434 | it may contain another object that must be constructed from a KeyVal.
|
---|
435 | In order to let the sub-object read the correct keywords from the
|
---|
436 | KeyVal, without knowledge of the containing objects keyword prefix,
|
---|
437 | a PrefixKeyVal can be constructed. For example, the code
|
---|
438 | \code
|
---|
439 | class A: public DescribedClass {
|
---|
440 | double f0_;
|
---|
441 | public:
|
---|
442 | A(const Ref<KeyVal> &keyval): f0_(keyval->doublevalue("f0")) {}
|
---|
443 | }
|
---|
444 | class B: public DescribedClass {
|
---|
445 | double f1_;
|
---|
446 | Ref<A> a_;
|
---|
447 | public:
|
---|
448 | B(const Ref<KeyVal> &keyval):
|
---|
449 | f1_(keyval->doublevalue("f1")),
|
---|
450 | a_(new PrefixKeyVal(keyval,"a"))
|
---|
451 | {}
|
---|
452 | };
|
---|
453 | \endcode
|
---|
454 | can be used to read ParsedKeyVal input that looks like
|
---|
455 | <pre>
|
---|
456 | b\<B>: (
|
---|
457 | f1 = 1.0
|
---|
458 | a\<A>: (
|
---|
459 | f0 = 2.0
|
---|
460 | )
|
---|
461 | )
|
---|
462 | </pre>
|
---|
463 | */
|
---|
464 | class PrefixKeyVal : public KeyVal {
|
---|
465 | private:
|
---|
466 | char* prefix;
|
---|
467 | Ref<KeyVal> keyval;
|
---|
468 | void setup(const char*,int,int,int,int,int);
|
---|
469 | int getnewprefixkey(const char*key,char*newkey);
|
---|
470 | // do not allow a copy constructor or assignment
|
---|
471 | PrefixKeyVal(const PrefixKeyVal&);
|
---|
472 | void operator=(const PrefixKeyVal&);
|
---|
473 | int key_exists(const char*);
|
---|
474 | Ref<KeyValValue> key_value(const char*,
|
---|
475 | const KeyValValue& def);
|
---|
476 | public:
|
---|
477 | /** @name Constructors.
|
---|
478 | Construct a PrefixKeyVal, using the given prefix and indices. */
|
---|
479 | //@{
|
---|
480 | PrefixKeyVal(const Ref<KeyVal>&,int i);
|
---|
481 | PrefixKeyVal(const Ref<KeyVal>&,int i,int j);
|
---|
482 | PrefixKeyVal(const Ref<KeyVal>&,int i,int j,int k);
|
---|
483 | PrefixKeyVal(const Ref<KeyVal>&,int i,int j,int k,int l);
|
---|
484 | PrefixKeyVal(const Ref<KeyVal>&,const char*prefix);
|
---|
485 | PrefixKeyVal(const Ref<KeyVal>&,const char*prefix,int i);
|
---|
486 | PrefixKeyVal(const Ref<KeyVal>&,const char*prefix,int i,int j);
|
---|
487 | PrefixKeyVal(const Ref<KeyVal>&,const char*prefix,int i,int j,int k);
|
---|
488 | PrefixKeyVal(const Ref<KeyVal>&,const char*prefix,int i,int j,int k,int l);
|
---|
489 | //@}
|
---|
490 | ~PrefixKeyVal();
|
---|
491 | void errortrace(std::ostream&fp=ExEnv::err0());
|
---|
492 | void dump(std::ostream&fp=ExEnv::err0());
|
---|
493 | };
|
---|
494 |
|
---|
495 | class IPV2;
|
---|
496 | /** Converts textual information into keyword/value assocations. The
|
---|
497 | parsing is done with an IPV2 object. The \ref keyval for more
|
---|
498 | information on the input format. */
|
---|
499 | class ParsedKeyVal : public StringKeyVal {
|
---|
500 | private:
|
---|
501 | int nfile;
|
---|
502 | char**file;
|
---|
503 | int nfp;
|
---|
504 | IPV2* ipv2;
|
---|
505 | // do not allow a copy constructor or assignment
|
---|
506 | ParsedKeyVal(const ParsedKeyVal&);
|
---|
507 | void operator=(const ParsedKeyVal&);
|
---|
508 | public:
|
---|
509 | /// Create an empty ParsedKeyVal.
|
---|
510 | ParsedKeyVal();
|
---|
511 | /// Parse the given input file.
|
---|
512 | ParsedKeyVal(const char*file);
|
---|
513 | /// Read input from s.
|
---|
514 | ParsedKeyVal(std::istream&s);
|
---|
515 | /** Use the given IPV2* object. The new ParsedKeyVal
|
---|
516 | takes wnership of the passed IPV2 object. */
|
---|
517 | ParsedKeyVal(IPV2*);
|
---|
518 | /** This ctor is given a string which is used to form keywords
|
---|
519 | that are sought in the keyval argument. The associated values
|
---|
520 | are used to construct file names that are used to initialize
|
---|
521 | the ParsedKeyVal. The keywords sought are string'dir' for the
|
---|
522 | directory prefix and string'files' for an array of file names. */
|
---|
523 | ParsedKeyVal(const char*,const Ref<KeyVal>&);
|
---|
524 | /// Cleanup, deleting the IPV2 object.
|
---|
525 | ~ParsedKeyVal();
|
---|
526 |
|
---|
527 | /** This is like the ParsedKeyVal(const char*,const Ref<KeyVal>&)
|
---|
528 | ctor, but writes the contents of the files to the given ostream. */
|
---|
529 | static void cat_files(const char*,const Ref<KeyVal>&,std::ostream &o);
|
---|
530 |
|
---|
531 | /// Read input data from the given filename
|
---|
532 | void read(const char*);
|
---|
533 | /// Read input data from the given stream.
|
---|
534 | void read(std::istream&);
|
---|
535 | /// Read input data from the given string.
|
---|
536 | void parse_string(const char *);
|
---|
537 |
|
---|
538 | /** @name Overrides of parent members.
|
---|
539 | See parent class documentation. */
|
---|
540 | //@{
|
---|
541 | const char* stringrep(const char*);
|
---|
542 | const char* classname(const char*);
|
---|
543 | const char* truekeyword(const char*);
|
---|
544 | void errortrace(std::ostream&fp=ExEnv::err0());
|
---|
545 | void dump(std::ostream&fp=ExEnv::err0());
|
---|
546 | void print_unseen(std::ostream&fp=ExEnv::out0());
|
---|
547 | int have_unseen();
|
---|
548 | //@}
|
---|
549 | };
|
---|
550 |
|
---|
551 | }
|
---|
552 |
|
---|
553 | #endif /* _KeyVal_h */
|
---|
554 |
|
---|
555 | // Local Variables:
|
---|
556 | // mode: c++
|
---|
557 | // c-file-style: "CLJ"
|
---|
558 | // End:
|
---|