| 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:
 | 
|---|