1 /*************************************************************************** 2 configlang.h - Config file parser with gettext support 3 ------------------- 4 begin : Thu May 15 2003 5 copyright : (C) 2003 by Gabor Torok 6 email : cctorok@yahoo.com 7 ***************************************************************************/ 8 9 /*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. * 15 * * 16 ***************************************************************************/ 17 #ifndef CONFIG_LANG_H 18 #define CONFIG_LANG_H 19 #pragma once 20 21 #include <vector> 22 #include <map> 23 #include <set> 24 25 class ConfigValue; 26 class ConfigNode; 27 class ConfigLang; 28 29 /// An individual configuration value. 30 31 class ConfigValue { 32 public: 33 enum TYPE { 34 STRING_TYPE = 0, 35 NUMBER_TYPE 36 }; 37 38 private: 39 int type; 40 bool translatable; 41 std::string valueStr, translateStr, original; 42 float valueNum; 43 44 public: 45 ConfigValue( char const* value ); 46 ConfigValue( ConfigValue const& that ); 47 ~ConfigValue(); 48 49 float getAsFloat(); 50 const char *getAsString(); getOriginal()51 inline std::string getOriginal() { 52 return original; 53 } 54 }; 55 56 /// A config node (cfg files can contain multiple blocks and levels). 57 58 class ConfigNode { 59 private: 60 ConfigNode *super; 61 ConfigLang *config; 62 std::string name; 63 std::string id; 64 std::map<std::string, ConfigValue*> values; 65 std::vector<ConfigNode*> children; 66 std::map<std::string, std::vector<ConfigNode*>*> childrenByName; 67 68 public: 69 ConfigNode( ConfigLang *config, std::string name ); 70 ~ConfigNode(); 71 void addChild( ConfigNode *node ); 72 void addValue( std::string name, ConfigValue *value ); 73 getConfig()74 inline ConfigLang *getConfig() { 75 return config; 76 } getName()77 inline std::string getName() { 78 return name; 79 } getId()80 inline std::string getId() { 81 return id; 82 } getValues()83 inline std::map<std::string, ConfigValue*>* getValues() { 84 return &values; 85 } getChildren()86 inline std::vector<ConfigNode*>* getChildren() { 87 return &children; 88 } getSuper()89 inline ConfigNode *getSuper() { 90 return super; 91 } setSuper(ConfigNode * super)92 inline void setSuper( ConfigNode *super ) { 93 this->super = super; 94 } 95 96 // convenience methods getValueAsString(std::string name)97 inline const char *getValueAsString( std::string name ) { 98 if ( values.find( name ) == values.end() ) { 99 return ""; 100 } else { 101 return values[ name ]->getAsString(); 102 } 103 } 104 getValueAsFloat(std::string name)105 inline float getValueAsFloat( std::string name ) { 106 if ( values.find( name ) == values.end() ) { 107 return 0; 108 } else { 109 return values[ name ]->getAsFloat(); 110 } 111 } 112 getValueAsInt(std::string name)113 inline int getValueAsInt( std::string name ) { 114 return toint( getValueAsFloat( name ) ); 115 } 116 getValueAsBool(std::string name)117 inline bool getValueAsBool( std::string name ) { 118 if ( values.find( name ) == values.end() ) { 119 return false; 120 } else { 121 return( !strcasecmp( values[ name ]->getAsString(), "true" ) || 122 !strcasecmp( values[ name ]->getAsString(), "yes" ) || 123 !strcasecmp( values[ name ]->getAsString(), "on" ) || 124 values[ name ]->getAsFloat() > 0 ); 125 } 126 } 127 128 void getKeys( std::set<std::string> *keyset ); 129 130 hasValue(std::string name)131 inline bool hasValue( std::string name ) { 132 return( values.find( name ) != values.end() ); 133 } 134 getChildrenByName(std::string name)135 inline std::vector<ConfigNode*> *getChildrenByName( std::string name ) { 136 if ( childrenByName.find( name ) == childrenByName.end() ) { 137 return NULL; 138 } else { 139 return childrenByName[ name ]; 140 } 141 } 142 143 void extendNode( std::string id ); 144 145 protected: 146 // copy node's values and children into this node 147 void copyFromNode( ConfigNode *node ); 148 149 }; 150 151 /// Configuration file parser. 152 153 class ConfigLang { 154 private: 155 std::map<std::string, ConfigNode*> idmap; 156 ConfigNode *document; 157 ConfigLang( char *config ); 158 ConfigLang( std::vector<std::string> *lines ); 159 void parse( char *config ); 160 void parse( std::vector<std::string> *lines ); 161 std::string cleanText( char *p, int n ); 162 163 public: 164 ~ConfigLang(); 165 void debug( ConfigNode *node, std::string indent, std::ostream &out ); debug()166 inline void debug() { 167 debug( document, "", std::cerr ); 168 } getDocument()169 inline ConfigNode *getDocument() { 170 return document; 171 } getIdMap()172 inline std::map<std::string, ConfigNode*> *getIdMap() { 173 return &idmap; 174 } 175 176 void setUpdate( char *message, int n = -1, int total = -1 ); 177 178 static ConfigLang *load( const std::string& file, bool absolutePath = false ); 179 static ConfigLang *fromString( char *str ); 180 static ConfigLang *fromString( std::vector<std::string> *lines ); 181 void save( std::string& file, bool absolutePath = false ); 182 }; 183 184 #endif 185 186