15 #ifndef CONFIG_PARSER_H
16 #define CONFIG_PARSER_H
33 #ifndef _GLIBCXX_CSTDIO
36 #ifndef _GLIBCXX_STRING
40 #define MAXCONFIGLINESIZE 200
45 typedef std::map<std::string, std::string> ConfigMap;
51 static char *unwhite(
char *
s) {
52 while (s[0] ==
' ') ++
s;
53 char *e = strchr(s, 0)-1;
55 while (e>s && isspace(e[0])) --e;
58 e[isspace(e[0]) ? 0 : 1] = 0;
69 FILE *in = fopen(filename.c_str(),
"rt");
78 char *content = unwhite(buffer);
79 if (content[0] && content[0] !=
'#') {
80 char *key = 0, *value = 0;
81 error = splitText(content,
'=', key, value);
82 if (!error && value[0] == 0) {
83 error =
"content missing behind '='";
87 ConfigMap::const_iterator found = entries.find(key);
88 if (found == entries.end()) {
96 if (error) error = makeError(lineno, error);
106 return GBS_global_string(
"%s (at entry '%s' in %s)", msg, forEntry.c_str(), filename.c_str());
108 GB_ERROR makeError(
int lineno,
const char *msg) {
109 return GBS_global_string(
"%s (at line #%i in %s)", msg, lineno, filename.c_str());
111 GB_ERROR makeError(
const char *msg) {
115 static GB_ERROR splitText(
char *text,
char separator,
char*& lhs,
char*& rhs) {
116 text = unwhite(text);
117 char *sep = strchr(text, separator);
122 rhs = unwhite(sep+1);
128 ConfigMap::const_iterator found = entries.find(key);
129 if (found == entries.end()) {
134 return &(found->second);
146 GB_ERROR parse_double(
const char *
s,
double& d) {
147 if (s[0] == 0)
return "floating point number expected";
157 GB_ERROR check_int_range(
int value,
int min_value,
int max_value) {
158 if (value<min_value || value>max_value) {
159 return GBS_global_string(
"%i outside allowed range [%i .. %i]", value, min_value, max_value);
163 GB_ERROR check_double_range(
double value,
double min_value,
double max_value) {
164 if (value<min_value || value>max_value) {
165 return GBS_global_string(
"%f outside allowed range [%f .. %f]", value, min_value, max_value);
169 GB_ERROR check_bool_range(
int value) {
170 if (value<0 || value>1) {
176 void parseInt(
const std::string& key,
int& value) {
177 const std::string *val = parser.getValue(key, error);
178 if (val) value = atoi(val->c_str());
181 void parseInt_checked(
const std::string& key,
int& value,
int min_value,
int max_value) {
182 parseInt(key, value);
184 error = check_int_range(value, min_value, max_value);
185 if (error) error = parser.makeError(key, error);
189 void parseIntRange(
const std::string& key,
int& low,
int& high) {
190 const std::string *val = parser.getValue(key, error);
195 error = ConfigParser::splitText(range,
',', lhs, rhs);
200 error =
GBS_global_string(
"Invalid range (%i has to be smaller than %i)", low, high);
206 if (error) error = parser.makeError(key, error);
210 void parseIntRange_checked(
const std::string& key,
int& low,
int& high,
int min_value,
int max_value) {
211 parseIntRange(key, low, high);
213 error = check_int_range(low, min_value, max_value);
214 if (!error) error = check_int_range(high, min_value, max_value);
215 if (error) error = parser.makeError(key, error);
219 void parseBool(
const std::string& key,
bool&
boolean) {
223 error = check_bool_range(b);
224 if (error) error = parser.makeError(key, error);
225 else boolean =
static_cast<bool>(b);
229 void parseDouble(
const std::string& key,
double& value) {
230 const std::string *val = parser.getValue(key, error);
232 error = parse_double(val->c_str(), value);
236 void parseDouble_checked(
const std::string& key,
double& value,
double min_value,
double max_value) {
237 parseDouble(key, value);
239 error = check_double_range(value, min_value, max_value);
240 if (error) error = parser.makeError(key, error);
244 void parseDoubleRange(
const std::string& key,
double& low,
double& high) {
245 const std::string *val = parser.getValue(key, error);
250 error = ConfigParser::splitText(range,
',', lhs, rhs);
251 if (!error) error = parse_double(lhs, low);
252 if (!error) error = parse_double(rhs, high);
253 if (!error && low>high) {
254 error =
GBS_global_string(
"Invalid range (%f has to be smaller than %f)", low, high);
259 if (error) error = parser.makeError(key, error);
263 void parseDoubleRange_checked(
const std::string& key,
double& low,
double& high,
double min_value,
double max_value) {
264 parseDoubleRange(key, low, high);
266 error = check_double_range(low, min_value, max_value);
267 if (!error) error = check_double_range(high, min_value, max_value);
268 if (error) error = parser.makeError(key, error);
277 virtual ~ConfigBase() {}
283 #undef MAXCONFIGLINESIZE
287 #error config_parser.h included twice
288 #endif // CONFIG_PARSER_H
return string(buffer, length)
char * ARB_strdup(const char *str)
const char * GBS_global_string(const char *templat,...)
char buffer[MESSAGE_BUFFERSIZE]
static void error(const char *msg)
#define MAXCONFIGLINESIZE
GB_write_int const char s