$search
00001 #include "utilmm/configfile/configfile.hh" 00002 #include "utilmm/configfile/exceptions.hh" 00003 00004 #include <boost/regex.hpp> 00005 00006 #include <fstream> 00007 #include <sstream> 00008 00009 using std::fstream; 00010 using std::string; 00011 using std::stringbuf; 00012 using namespace utilmm; 00013 00014 using boost::regex; 00015 using boost::smatch; 00016 00017 parse_error::parse_error(int line_, std::string const& message_) 00018 : line(line_), message(message_) {} 00019 00020 config_file::config_file(std::string const& name) 00021 { 00022 try { read(name); } 00023 catch(...) { 00024 clear(); 00025 throw; 00026 } 00027 } 00028 00029 void config_file::read(const std::string& name) 00030 { 00031 clear(); 00032 00033 fstream file; 00034 file.open(name.c_str(), fstream::in); 00035 if (! file.is_open()) 00036 throw not_found(name); 00037 00038 static const string 00039 regexp_header("^[[:blank:]]*"), 00040 regexp_trail("[[:blank:]]*(?:#.*)?$"); 00041 00042 static regex 00043 rx_empty(regexp_header + regexp_trail), 00044 rx_name(regexp_header + "([[:alnum:]_-]+)([^#]*)" + regexp_trail), 00045 rx_attribute(regexp_header + ":[[:blank:]]*([^#]+)" + regexp_trail), 00046 rx_open_bracket(regexp_header + "\\{" + regexp_trail), 00047 rx_close_bracket(regexp_header + "\\}" + regexp_trail); 00048 00049 enum { Normal, FindBracket } mode; 00050 mode = Normal; 00051 00052 config_set* cur_set = this; 00053 00054 int line_number = 1; 00055 stringbuf linebuf; 00056 const string empty_string; 00057 while (! file.eof()) 00058 { 00059 while (file.peek() == '\n') 00060 { 00061 ++line_number; 00062 file.ignore(); 00063 } 00064 00065 file.get(linebuf); 00066 const string line(linebuf.str()); 00067 linebuf.str(empty_string); 00068 00069 smatch result; 00070 if (regex_match(line, rx_empty)) continue; 00071 00072 if (mode == FindBracket) 00073 { 00074 if (! regex_match(line, rx_open_bracket)) 00075 throw parse_error(line_number, "expected '{', found " + line); 00076 00077 mode = Normal; 00078 } 00079 else if (regex_match(line, result, rx_name)) 00080 { 00081 string key = result[1]; 00082 string value = result[2]; 00083 00084 smatch attribute_value; 00085 00086 if (value.empty() 00087 || regex_match(value, rx_open_bracket)) 00088 { 00089 mode = value.empty() ? FindBracket : Normal; 00090 00091 config_set* new_set = new config_set(cur_set); 00092 cur_set->insert( key, new_set ); 00093 cur_set = new_set; 00094 } 00095 else if (regex_match(value, attribute_value, rx_attribute)) 00096 cur_set->insert( key, attribute_value[1] ); 00097 else 00098 throw parse_error(line_number, "expected '" + key + ": value', found " + key + value); 00099 } 00100 else if (regex_match(line, rx_close_bracket)) 00101 { 00102 if (cur_set -> parent() == 0) 00103 throw parse_error(line_number, "unmatched bracket"); 00104 cur_set = cur_set->parent(); 00105 } 00106 else 00107 throw parse_error(line_number, "expected \"key: value\", found " + line); 00108 } 00109 00110 if (mode == FindBracket) 00111 throw parse_error(line_number, "expected '{', got end of file"); 00112 else if (cur_set -> parent()) 00113 throw parse_error(line_number, "expected '}' before end of file"); 00114 } 00115