00001 #ifndef IOTRCONFIGURATION
00002 #define IOTRCONFIGURATION
00003
00004 #include <map>
00005 #include <string>
00006 #include <iostream>
00007 #include "IotrRefCount.hh"
00008 #include "IotrHandle.hh"
00009 #include <regex.h>
00010 #include <errno.h>
00011
00012 enum { configFound = 0, configUnused, configNotFound, expectedString,
00013 expectedReal, expectedInteger, expectedConfiguration };
00014
00019 template<typename T>
00020 struct IotrOption {
00021 const char * key;
00022 T value;
00023 const char * comment;
00024 };
00025
00026 typedef IotrOption<double> FloatOption;
00027 typedef IotrOption<int> IntOption;
00028 typedef IotrOption<const char*> CharOption;
00029
00030 class IotrConfiguration;
00035 class IotrConfigOption : public IotrRefCount {
00036 friend class IotrConfiguration;
00037 protected:
00038 int mMarked;
00039 int mIsScalar;
00040 public:
00041 IotrConfigOption( int isScalar ) :
00042 mMarked(configUnused), mIsScalar( isScalar ) {}
00043 int isScalar() const { return mIsScalar; }
00044 int marked() const { return mMarked; }
00045 virtual void write( std::ostream &, const char * indent ) const = 0;
00046 };
00047
00048 typedef Handle<IotrConfigOption> IotrConfigOptionHandle;
00049
00054 class IotrConfiguration : public IotrRefCount {
00055 protected:
00056 std::map<std::string,IotrConfigOptionHandle> mConfig;
00057 template<typename T>
00058 int findOptionT(T & opt, const char * key,
00059 int mark, int & err, int expectedT ) const;
00060 public:
00061 int findOption( IotrConfiguration &, const char * key,
00062 int mark, int & err ) const;
00063 int findOption( std::string & opt, const char * key,
00064 int mark, int & err ) const
00065 {
00066 return this->findOptionT( opt, key, mark, err, expectedString );
00067 }
00068 int findOption( double & opt, const char * key,
00069 int mark, int & err ) const
00070 {
00071 return this->findOptionT( opt, key, mark, err, expectedReal );
00072 }
00073 int findOption( int & opt, const char * key,
00074 int mark, int & err ) const
00075 {
00076 return this->findOptionT( opt, key, mark, err, expectedInteger );
00077 }
00078
00079 void insert( const char * key, const char * value,
00080 const char * comment = 0 );
00081 void insert( const char * key, int value, const char * comment = 0 );
00082 void insert( const char * key, double value, const char * comment = 0 );
00083 void insert( const char * key, IotrConfiguration * config,
00084 const char * comment = 0 );
00085 template<typename T>
00086 void insertList( IotrOption<T> opts[] );
00087
00088 void shallowCopy( const IotrConfiguration & config )
00089 { mConfig = config.mConfig; }
00090 void reportErrors() const;
00091 int findErrors( IotrConfiguration & unused,
00092 IotrConfiguration & bad ) const;
00093
00094 int insertShorthand( const char opt[] );
00095
00096 void overrideWith( const IotrConfiguration & config );
00097
00098 void write( std::ostream & s, const char * indent,
00099 const char * comment = 0 ) const;
00100 int empty() const { return mConfig.empty(); }
00101
00102 virtual void inspect() const { write( std::cout, "" ); }
00103 };
00104
00105
00110 class IotrConfigParser {
00111 protected:
00112 regex_t beginConfigDoc, beginDoc, endDoc, comment, scalarTag, complexTag;
00113
00114 int read_config_line( std::istream & in, std::string & s, int & line );
00115 int readDocument( std::istream & in, IotrConfiguration & config,
00116 std::string & s,
00117 int & line, int indent_level );
00118 public:
00119 IotrConfigParser();
00120 ~IotrConfigParser();
00121 int readStream( std::istream & optStream, IotrConfiguration & config );
00122 };
00123
00124
00125 typedef Handle<IotrConfiguration> IotrConfigurationHandle;
00126
00127
00128 #endif