[0b990d] | 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:
|
---|