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