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