Annotation of /home/cljanss/src/SC/src/lib/util/keyval/keyval.h for ./mpqc.vmon.0018
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.h>
36 #include <stdlib.h>
37 #include <stdarg.h>
38
39 #include <util/container/avlmap.h>
40 #include <util/class/class.h>
41 #include <util/keyval/keyvalval.h>
42
43 class KeyValKeyword {
44 private:
45 char* keyword_;
46 public:
47 KeyValKeyword();
48 KeyValKeyword(const char* name);
49 KeyValKeyword(const KeyValKeyword&);
50 ~KeyValKeyword();
51 KeyValKeyword& operator=(const KeyValKeyword&);
52 int operator==(const KeyValKeyword& ck) const;
53 int operator<(const KeyValKeyword& ck) const;
54 int hash() const;
55 inline int cmp(const KeyValKeyword&ck) const
56 {
57 if (!keyword_) {
58 if (!ck.keyword_) return 0;
59 return -1;
60 }
61 1 0 0 0 0 0 0 0 0 0 if (!ck.keyword_) return 1;
62 return strcmp(keyword_,ck.keyword_);
63 }
64 inline const char* name() const {return keyword_;}
65 };
66
67 /**
68 The KeyVal class is designed to simplify the process of allowing
69 a user to specify keyword/value associations to a C++ program. A
70 flexible input style and ease of use for the programmer is achieved with
71 this method. Keywords are represented by null terminated character arrays.
72 The keywords are organized hierarchially, in a manner similar to the way
73 that many file systems are organized. One character is special,
74 ":", which is used to separate the various hierarchial labels,
75 which are referred to as "segments", in the keyword.
76
77 A convention for specifying arrays is provided by KeyVal. Each
78 index of the array is given by appending a segment containing the
79 character representation of the index. Thus, "array:3:4" would be
80 a the keyword corresponding to fourth row and fifth column of
81 "array", since indexing starts at zero.
82
83 To allow the KeyVal class to have associations that can represent
84 data for classes, the keyword can be associated with a class as well as
85 a value. This permits polymorphic data to be unambiguously represented
86 by keyword/value associations. Most use of KeyVal need not be
87 concerned with this.
88 */
89 class KeyVal: public RefCount {
90 // these classes need to directly access the key_value member
91 friend class AggregateKeyVal;
92 friend class PrefixKeyVal;
93 public:
94 enum {MaxKeywordLength = 256};
95 enum KeyValError { OK, HasNoValue, WrongType,
96 UnknownKeyword, OperationFailed };
97 private:
98 KeyValError errcod;
99 // do not allow a copy constructor or assignment
100 KeyVal(const KeyVal&);
101 void operator=(const KeyVal&);
102 protected:
103 int verbose_;
104
105 KeyVal();
106
107 /// Set the current error condition.
108 void seterror(KeyValError err);
109 /// Set the current error condition.
110 void seterror(KeyValValue::KeyValValueError err);
111
112 /// Ultimately called by exists.
113 virtual int key_exists(const char*) = 0;
114 /// Ultimately called by count.
115 virtual int key_count(const char* =0);
116 /// Ultimately called by value.
117 virtual Ref<KeyValValue> key_value(const char*,
118 const KeyValValue& def) = 0;
119 /// Ultimately called by booleanvalue.
120 virtual int key_booleanvalue(const char*,const KeyValValue& def);
121 /// Ultimately called by doublevalue.
122 virtual double key_doublevalue(const char* key,const KeyValValue& def);
123 /// Ultimately called by floatvalue.
124 virtual float key_floatvalue(const char* key,const KeyValValue& def);
125 /// Ultimately called by charvalue.
126 virtual char key_charvalue(const char* key,const KeyValValue& def);
127 /// Ultimately called by intvalue.
128 virtual int key_intvalue(const char* key,const KeyValValue& def);
129 /// Ultimately called by pcharvalue.
130 virtual char* key_pcharvalue(const char* key,const KeyValValue& def);
131 /// Ultimately called by describedclassvalue.
132 virtual Ref<DescribedClass> key_describedclassvalue(const char* key,
133 const KeyValValue& def);
134
135 public:
136 virtual ~KeyVal();
137
138 // For nonindexed things. If a subclass defines one of these,
139 // then the overloaded functions will be hidden. The key_... functions
140 // should be overridden instead.
141
142 /** This takes as its only argument a keyword.
143 Returns 1 if the keyword has a value and 0 otherwise. */
144 int exists(const char*);
145 /** If the value of a keyword is an array, then return its length.
146 If no arguments are given then the top level will be checked to
147 see if it is an array and, if so, the number of elements will be
148 counted. */
149 int count(const char* =0);
150 /// Return the value associated with the keyword.
151 Ref<KeyValValue> value(const char* = 0,
152 const KeyValValue& def=KeyValValue());
153 /// Returns the boolean value (0 = false, 1 = true) of key.
154 int booleanvalue(const char* key = 0,
155 const KeyValValue& def=KeyValValueboolean());
156 /// Returns the double value of key.
157 double doublevalue(const char* key = 0,
158 const KeyValValue& def=KeyValValuedouble());
159 /// Returns the float value of key.
160 float floatvalue(const char* key = 0,
161 const KeyValValue& def=KeyValValuefloat());
162 /// Returns the char value of key.
163 char charvalue(const char* key = 0,
164 const KeyValValue& def=KeyValValuechar());
165 /// Returns the int value of key.
166 int intvalue(const char* key = 0,
167 const KeyValValue& def=KeyValValueint());
168 /** Returns a copy of the string representation of the key's
169 value. Storage for the copy is obtained with new. */
170 char* pcharvalue(const char* key = 0,
171 const KeyValValue& def=KeyValValuepchar());
172 /// Returns a reference to an object of type DescribedClass.
173 Ref<DescribedClass> describedclassvalue(const char* key = 0,
174 const KeyValValue& def=KeyValValueRefDescribedClass());
175
176 // For vectors:
177 int exists(const char*,int);
178 int count(const char*,int);
179 int booleanvalue(const char*,int,
180 const KeyValValue& def=KeyValValueboolean());
181 double doublevalue(const char* key,int,
182 const KeyValValue& def=KeyValValuedouble());
183 float floatvalue(const char* key,int,
184 const KeyValValue& def=KeyValValuefloat());
185 char charvalue(const char* key,int,
186 const KeyValValue& def=KeyValValuechar());
187 int intvalue(const char* key,int,
188 const KeyValValue& def=KeyValValueint());
189 char* pcharvalue(const char* key,int,
190 const KeyValValue& def=KeyValValuepchar());
191 Ref<DescribedClass> describedclassvalue(const char* key,int,
192 const KeyValValue& def=KeyValValueRefDescribedClass());
193
194 int exists(int i);
195 int count(int i);
196 int booleanvalue(int i,
197 const KeyValValue& def=KeyValValueboolean());
198 double doublevalue(int i,
199 const KeyValValue& def=KeyValValuedouble());
200 float floatvalue(int i,
201 const KeyValValue& def=KeyValValuefloat());
202 char charvalue(int i,
203 const KeyValValue& def=KeyValValuechar());
204 int intvalue(int i,
205 const KeyValValue& def=KeyValValueint());
206 char* pcharvalue(int i,
207 const KeyValValue& def=KeyValValuepchar());
208 Ref<DescribedClass> describedclassvalue(int i,
209 const KeyValValue& def=KeyValValueRefDescribedClass());
210
211 // For arrays:
212 int exists(const char*,int,int);
213 int count(const char*,int,int);
214 int booleanvalue(const char*,int,int,
215 const KeyValValue& def=KeyValValueboolean());
216 double doublevalue(const char* key,int,int,
217 const KeyValValue& def=KeyValValuedouble());
218 float floatvalue(const char* key,int,int,
219 const KeyValValue& def=KeyValValuefloat());
220 char charvalue(const char* key,int,int,
221 const KeyValValue& def=KeyValValuechar());
222 int intvalue(const char* key,int,int,
223 const KeyValValue& def=KeyValValueint());
224 char* pcharvalue(const char* key,int,int,
225 const KeyValValue& def=KeyValValuepchar());
226 Ref<DescribedClass> describedclassvalue(const char* key,int,int,
227 const KeyValValue& def=KeyValValueRefDescribedClass());
228
229 int exists(int i,int j);
230 int count(int i,int j);
231 int booleanvalue(int i,int j,
232 const KeyValValue& def=KeyValValueboolean());
233 double doublevalue(int i,int j,
234 const KeyValValue& def=KeyValValuedouble());
235 float floatvalue(int i,int j,
236 const KeyValValue& def=KeyValValuefloat());
237 char charvalue(int i,int j,
238 const KeyValValue& def=KeyValValuechar());
239 int intvalue(int i,int j,
240 const KeyValValue& def=KeyValValueint());
241 char* pcharvalue(int i,int j,
242 const KeyValValue& def=KeyValValuepchar());
243 Ref<DescribedClass> describedclassvalue(int i,int j,
244 const KeyValValue& def=KeyValValueRefDescribedClass());
245
246 // For all else:
247 int Va_exists(const char*,int,...);
248 int Va_count(const char*,int,...);
249 int Va_booleanvalue(const char*,int,...);
250 double Va_doublevalue(const char* key,int,...);
251 float Va_floatvalue(const char* key,int,...);
252 char Va_charvalue(const char* key,int,...);
253 int Va_intvalue(const char* key,int,...);
254 char* Va_pcharvalue(const char* key,int,...);
255 Ref<DescribedClass> Va_describedclassvalue(const char* key,int,...);
256
257 /// Return the current error condition.
258 KeyValError error();
259 /// Return a textual representation of err.
260 const char* errormsg(KeyValError err);
261 /// Return a textual representation of the current error.
262 const char* errormsg();
263
264 virtual void errortrace(std::ostream&fp=ExEnv::err());
265 virtual void dump(std::ostream&fp=ExEnv::err());
266
267 /// Print keywords that were never looked at, if possible.
268 virtual void print_unseen(std::ostream&fp=ExEnv::out());
269 /** Return 1 if there were unseen keywords, 0 if there are
270 none, or -1 this keyval doesn't keep track of unseen
271 keywords. */
272 virtual int have_unseen();
273
274 /// Control printing of assignments.
275 void verbose(int v) { verbose_ = v; }
276 /// Returns nonzero if assignments are printed.
277 int verbose() const { return verbose_; }
278 };
279
280
281
282 // this class allows keyval associations to be set up by the program,
283 // rather than determined by an external file
284 class AssignedKeyVal: public KeyVal {
285 private:
286 AVLMap<KeyValKeyword,Ref<KeyValValue> > _map;
287 // do not allow a copy constructor or assignment
288 AssignedKeyVal(const AssignedKeyVal&);
289 void operator=(const AssignedKeyVal&);
290 protected:
291 int key_exists(const char*);
292 Ref<KeyValValue> key_value(const char*,
293 const KeyValValue& def);
294 public:
295 AssignedKeyVal();
296 ~AssignedKeyVal();
297
298 void assign(const char*, const Ref<KeyValValue>&);
299 void assign(const char*, double);
300 void assignboolean(const char*, int);
301 void assign(const char*, float);
302 void assign(const char*, char);
303 void assign(const char*, int);
304 void assign(const char*, const char*);
305 void assign(const char*, const Ref<DescribedClass>&);
306
307 void clear();
308 };
309
310
311
312 class StringKeyVal: public KeyVal {
313 private:
314 // once a described class is found it is kept here so
315 // multiple references to it return the same instance
316 AVLMap<KeyValKeyword,Ref<KeyValValue> > _map;
317 // do not allow a copy constructor or assignment
318 StringKeyVal(const StringKeyVal&);
319 void operator=(const StringKeyVal&);
320 protected:
321 StringKeyVal();
322 int key_exists(const char*);
323 Ref<KeyValValue> key_value(const char*,
324 const KeyValValue& def);
325 public:
326 virtual ~StringKeyVal();
327 virtual const char* stringvalue(const char *) = 0;
328 // returns the name of the exact class the object at the keyword
329 virtual const char* classname(const char*);
330 // returns a string which is the actual keyword if some sort
331 // of variable substitution takes place (needed to make multiple
332 // references to the same object work in input files)
333 virtual const char* truekeyword(const char*);
334
335 virtual void errortrace(std::ostream&fp=ExEnv::err());
336 virtual void dump(std::ostream&fp=ExEnv::err());
337 };
338
339 class AggregateKeyVal : public KeyVal {
340 private:
341 enum { MaxKeyVal = 4 };
342 Ref<KeyVal> kv[MaxKeyVal];
343 Ref<KeyVal> getkeyval(const char*key);
344 // do not allow a copy constructor or assignment
345 AggregateKeyVal(const AggregateKeyVal&);
346 void operator=(const AggregateKeyVal&);
347 protected:
348 int key_exists(const char*);
349 Ref<KeyValValue> key_value(const char*,
350 const KeyValValue& def);
351 public:
352 AggregateKeyVal(const Ref<KeyVal>&);
353 AggregateKeyVal(const Ref<KeyVal>&,const Ref<KeyVal>&);
354 AggregateKeyVal(const Ref<KeyVal>&,const Ref<KeyVal>&,const Ref<KeyVal>&);
355 AggregateKeyVal(const Ref<KeyVal>&,const Ref<KeyVal>&,const Ref<KeyVal>&,
356 const Ref<KeyVal>&);
357 ~AggregateKeyVal();
358 void errortrace(std::ostream&fp=ExEnv::err());
359 void dump(std::ostream&fp=ExEnv::err());
360 };
361
362 class PrefixKeyVal : public KeyVal {
363 private:
364 char* prefix;
365 Ref<KeyVal> keyval;
366 void setup(const char*,int,int,int,int,int);
367 int getnewprefixkey(const char*key,char*newkey);
368 // do not allow a copy constructor or assignment
369 PrefixKeyVal(const PrefixKeyVal&);
370 void operator=(const PrefixKeyVal&);
371 int key_exists(const char*);
372 Ref<KeyValValue> key_value(const char*,
373 const KeyValValue& def);
374 public:
375 PrefixKeyVal(const Ref<KeyVal>&,int);
376 PrefixKeyVal(const Ref<KeyVal>&,int,int);
377 PrefixKeyVal(const Ref<KeyVal>&,int,int,int);
378 PrefixKeyVal(const Ref<KeyVal>&,int,int,int,int);
379 PrefixKeyVal(const Ref<KeyVal>&,const char*);
380 PrefixKeyVal(const Ref<KeyVal>&,const char*,int);
381 PrefixKeyVal(const Ref<KeyVal>&,const char*,int,int);
382 PrefixKeyVal(const Ref<KeyVal>&,const char*,int,int,int);
383 PrefixKeyVal(const Ref<KeyVal>&,const char*,int,int,int,int);
384 // old CTOR syntax (use the above instead)
385 PrefixKeyVal(const char*,const Ref<KeyVal>&);
386 PrefixKeyVal(const char*,const Ref<KeyVal>&,int);
387 PrefixKeyVal(const char*,const Ref<KeyVal>&,int,int);
388 PrefixKeyVal(const char*,const Ref<KeyVal>&,int,int,int);
389 PrefixKeyVal(const char*,const Ref<KeyVal>&,int,int,int,int);
390 ~PrefixKeyVal();
391 void errortrace(std::ostream&fp=ExEnv::err());
392 void dump(std::ostream&fp=ExEnv::err());
393 };
394
395 class IPV2;
396 /** Converts textual information into keyword/value assocations. The
397 parsing is done with an IPV2 object. The \ref keyval for more
398 information on the input format. */
399 class ParsedKeyVal : public StringKeyVal {
400 private:
401 int nfile;
402 char**file;
403 int nfp;
404 IPV2* ipv2;
405 // do not allow a copy constructor or assignment
406 ParsedKeyVal(const ParsedKeyVal&);
407 void operator=(const ParsedKeyVal&);
408 public:
409 /// Create an empty ParsedKeyVal.
410 ParsedKeyVal();
411 /// Parse the given input file.
412 ParsedKeyVal(const char*file);
413 /// Read input from s.
414 ParsedKeyVal(std::istream&s);
415 /** Use the given IPV2* object. The new ParsedKeyVal
416 takes wnership of the passed IPV2 object. */
417 ParsedKeyVal(IPV2*);
418 /** This ctor is given a string which is used to form keywords
419 that are sought in the keyval argument. The associated values
420 are used to construct file names that are used to initialize
421 the ParsedKeyVal. The keywords sought are string'dir' for the
422 directory prefix and string'files' for an array of file names. */
423 ParsedKeyVal(const char*,const Ref<KeyVal>&);
424 /// Cleanup, deleting the IPV2 object.
425 ~ParsedKeyVal();
426
427 /** This is like the ParsedKeyVal(const char*,const Ref<KeyVal>&)
428 ctor, but writes the contents of the files to the given ostream. */
429 static void cat_files(const char*,const Ref<KeyVal>&,std::ostream &o);
430
431 /// Read input data from the given filename
432 void read(const char*);
433 /// Read input data from the given stream.
434 void read(std::istream&);
435 /// Read input data from the given string.
436 void parse_string(const char *);
437
438 // Overrides of parent members.
439 const char* stringvalue(const char*);
440 const char* classname(const char*);
441 const char* truekeyword(const char*);
442 void errortrace(std::ostream&fp=ExEnv::err());
443 void dump(std::ostream&fp=ExEnv::err());
444 void print_unseen(std::ostream&fp=ExEnv::out());
445 int have_unseen();
446 };
447
448
449
450 #endif /* _KeyVal_h */
451
452 // Local Variables:
453 // mode: c++
454 // c-file-style: "CLJ"
455 // End:
456