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