00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "conf/conf.h"
00027
00028
00029 #include <cctype>
00030 #include <cstring>
00031 #include <iostream>
00032
00033
00034 #include "include/config.h"
00035 #include "io/mappedFile.h"
00036 #include "Common/util.h"
00037 #include "conf/conf_bool.h"
00038
00039 using namespace std;
00040 using namespace IXE::io;
00041 using namespace IXE::Text;
00042
00043 namespace IXE {
00044
00045 int Configuration::current_config_file_line_no = 0;
00046
00047 conf<bool> VerboseConfig("VerboseConfig", false);
00048
00049
00071
00072
00073
00074 Configuration::Map&
00075 Configuration::variables()
00076 {
00077 static Map m;
00078 return m;
00079 }
00080
00084 void
00085 Configuration::insert(Configuration::Item* var)
00086 {
00087 variables()[var->name()] = var;
00088 }
00089
00090
00096
00097
00098 void
00099 Configuration::load(char const* file_name)
00100 {
00101 try {
00102 mappedFile conf_file(file_name);
00103
00104 register int line_no = 0;
00105 register mappedFile::const_iterator c = conf_file.begin(), nl = c;
00106
00107 while (c != conf_file.end() && nl != conf_file.end()) {
00108 if (!(nl = ::strchr(c, '\n')))
00109
00110
00111
00112
00113 break;
00114 ++line_no;
00115
00116
00117
00118
00119
00120 while (c != nl && isspace((unsigned char)*c))
00121 ++c;
00122 if (c == nl || *c == '#')
00123 c = nl + 1;
00124 else if (c != nl) {
00125
00126
00127
00128 parseLine(c, line_no);
00129 }
00130 }
00131 } catch (MmapError&) {
00132 if (!::strcmp(file_name, ConfigFileDefault))
00133
00134
00135
00136
00137
00138 error() << "could not read configuration from \""
00139 << file_name << '"' << endl;
00140 }
00141 }
00142
00143 static
00144 int count_lines(char const* start, char const* end)
00145 {
00146 int count = 0;
00147 while ((start = ::strchr(start, '\n')) && start < end) {
00148 start++;
00149 count++;
00150 }
00151 return count;
00152 }
00153
00154 static inline void SKIP_EOL(char const*& x)
00155 {
00156 if (x[0] == '\r') {
00157 ++x;
00158 if (x[0] == '\n') ++x;
00159 } else if (x[0] == '\n') {
00160 ++x;
00161 if (x[0] == '\r') ++x;
00162 }
00163 }
00164
00165
00176
00177
00178 void
00179 Configuration::parseLine(char const*& line, int& line_no)
00180 {
00181 current_config_file_line_no = line_no;
00182 char const* varstart = next_token_line(line, " \r\t");
00183 char var[256];
00184 int len = line - varstart;
00185 ::strncpy(var, varstart, len);
00186 var[len] = '\0';
00187 Map::const_iterator const v = variables().find(var);
00188 if (v == variables().end()) {
00189 if (VerboseConfig)
00190 warning() << '"' << line << "\" in config. file unrecognized; ignored\n";
00191 } else {
00192
00193
00194
00195
00196 while (*line && line[0] != '\n' && isspace((unsigned char)*line))
00197 ++line;
00198 char const* start = line;
00199 if (line[0] != '\n')
00200 v->second->parseValue(line);
00201 line_no += count_lines(start, line);
00202
00203 char const* endline = ::strpbrk(line, "\n\r");
00204 if (endline) {
00205 line = endline;
00206 SKIP_EOL(line);
00207 }
00208 }
00209 }
00210
00211
00215
00216
00217 void
00218 Configuration::reset()
00219 {
00220 TRANSFORM_EACH(Configuration::Map, Configuration::variables(), v)
00221 v->second->reset();
00222 }
00223
00224
00234
00235
00236 ostream &
00237 Configuration::msg(ostream& o, char const* label)
00238 {
00239 if (current_config_file_line_no) {
00240 o << "config file line " << current_config_file_line_no;
00241 current_config_file_line_no = 0;
00242 }
00243 return o << ": " << label << ": ";
00244 }
00245
00246 }