1 /*--------------------------------------------------------------------------*\ 2 * ConfigFile class 3 * 4 * Input file consists of lines of text of the form 5 * name = value 6 * where 'name' is the look up key and 'value' is the resultant value 7 * 8 * '\' is the escape character and allows values to contain embedded '"' and 9 * '#' characters, as well as to do line continuation. 10 * To put '"' in a value use '\"'. To put '\' in a value use '\\'. 11 * 12 * Anything in double quotes is copied literally (except escape sequences). 13 * Outside of double quotes: 14 * '#' starts a comment; the rest of the line is ignored 15 * White space is ignored 16 * 17 *-------------------------------------------------------------------------- 18 * 19 * Created by Mark Huss <mark@mhuss.com> 20 * 21 * Developed and built using the mingw32 gcc compiler 2.95.2 22 * 23 * THIS SOFTWARE IS NOT COPYRIGHTED 24 * 25 * This source code is offered for use in the public domain. You may 26 * use, modify or distribute it freely. 27 * 28 * This code is distributed in the hope that it will be useful but 29 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY 30 * DISCLAMED. This includes but is not limited to warranties of 31 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 32 * 33 \*--------------------------------------------------------------------------*/ 34 35 #if !defined(CONFIG_FILE__H) 36 #define CONFIG_FILE__H 37 38 #include <stdio.h> // for FILE* 39 40 //---------------------------------------------------------------------------- 41 // CFList : a simple linked list class 42 // 43 class CFList { 44 public: CFList(const char * name,const char * value)45 CFList(const char* name, const char* value): m_next(0) { 46 m_name = strDup(name); 47 m_value = strDup(value); 48 } 49 ~CFList()50 ~CFList() { 51 delete [] m_name; m_name=0; 52 delete [] m_value; m_value=0; 53 54 // recursive delete 55 delete m_next; 56 m_next = 0; 57 } 58 59 void add(const char* name, const char* value); 60 void update(const char* name, const char* value); 61 62 const char* value(const char* name) const; 63 bool boolValue(const char* name) const; 64 int intValue(const char* name) const; 65 double dblValue(const char* name) const; 66 67 void dump( FILE* fp = stdout ) const; 68 69 private: CFList()70 CFList() {} // default c'tor not allowed 71 72 static char* strDup( const char* p ); 73 74 const char* m_name; 75 const char* m_value; 76 CFList* m_next; 77 }; // end class CFList 78 79 //---------------------------------------------------------------------------- 80 // the main class 81 82 class ConfigFile { 83 84 public: 85 // cheap way to define integer constants 86 enum { 87 NV_SEP_CHAR = '=', 88 COMMENT_CHAR = '#', 89 QUOTE_CHAR = '"', 90 ESC_CHAR = '\\', 91 BUFSIZE = 5120 92 }; 93 94 enum { 95 OK = 0, 96 INVALID_FILE_NAME, 97 FILE_NOT_FOUND, 98 NO_ENTRIES 99 }; 100 101 static bool debug; 102 103 // constructors ConfigFile()104 ConfigFile() : m_status( NO_ENTRIES ), m_items( "ConfigFile", "init" ) {} 105 ConfigFile(const char * fname)106 ConfigFile( const char* fname ) : m_items( "ConfigFile", "init" ) { 107 readAndParseFile( fname ); 108 } 109 110 // specify a new config file filename(const char * fname)111 int filename( const char* fname ) { return readAndParseFile( fname ); } 112 113 // retrieve a string value --return NULL if not found value(const char * name)114 const char* value( const char* name ) const { 115 return m_items.value( name ); 116 } 117 118 // retrieve a boolean value -- returns false if not found or name is not '[Tt]rue' boolValue(const char * name)119 int boolValue( const char* name ) const { 120 return m_items.boolValue( name ); 121 } 122 123 // retrieve an int value -- returns 0 if not found or name is not an int intValue(const char * name)124 int intValue( const char* name ) const { 125 return m_items.intValue( name ); 126 } 127 128 // retrieve a double value -- returns 0. if not found or name is not a double dblValue(const char * name)129 double dblValue( const char* name ) const { 130 return m_items.dblValue( name ); 131 } 132 133 // output all keys and values dump(FILE * fp)134 void dump( FILE* fp ) const { m_items.dump( fp ); } 135 status()136 int status() const { return m_status; } 137 138 private: 139 int m_status; 140 CFList m_items; 141 142 // config file path & name 143 const char* m_filename; 144 145 // load m_values 146 int readAndParseFile( const char* fname ); 147 148 bool compactBuffer(char* buf); 149 150 }; // end class ConfigFile 151 152 #endif /* #if !defined(CONFIG_FILE__H) */ 153