00001
00002 #include <string>
00003 #include <algorithm>
00004 #include <stdlib.h>
00005 #include "configuration.h"
00006 #include "datepattern.h"
00007 #include "path.h"
00008 #include "domain.h"
00009
00010 Configuration::Configuration(): format_(NONE), max_level_(0), select_(0) {
00011 }
00012
00013 Configuration::~Configuration() {
00014 delete select_;
00015 }
00016
00017 void
00018 Configuration::add_expression(Expression* e) {
00019 if (e) {
00020 if (!select_)
00021 select_ = new AndExpression();
00022 select_->add(e);
00023 }
00024 }
00025
00026 unsigned int
00027 Configuration::parse(istream& is) {
00028 string word;
00029 bool ok(true);
00030 criteria_.clear();
00031 unsigned int lineno(1);
00032 while (is >> word) {
00033 if (word.size() && word[0]=='#') {
00034 string junk;
00035 getline(is,junk);
00036 }
00037 else if (word=="format") {
00038 if (format_!=NONE)
00039 return lineno;
00040 ok = parse_format(is);
00041 }
00042 else if (word=="select")
00043 ok = parse_select(is);
00044 else if (word=="exclude")
00045 ok = parse_exclude(is);
00046 else
00047 return lineno;
00048 if (!ok)
00049 return lineno;
00050 ++lineno;
00051 }
00052 return 0;
00053 }
00054
00055 bool
00056 Configuration::parse_format(istream& is) {
00057 format_ = parse_criterium(is);
00058 if (format_ == NONE)
00059 return false;
00060 criteria_.insert(format_);
00061 if (parse_levels(is,levels_)) {
00062 if (levels_.size()==0) {
00063 levels_.insert(1);
00064 levels_.insert(2);
00065 levels_.insert(3);
00066 }
00067
00068 max_level_ = *(max_element(levels_.begin(),levels_.end()));
00069 }
00070 return true;
00071 }
00072
00073 bool
00074 Configuration::parse_select(istream& is) {
00075 Expression* e(parse_expression(is));
00076 if (e) {
00077 add_expression(e);
00078 return true;
00079 }
00080 return false;
00081 }
00082
00083
00084 Expression*
00085 Configuration::parse_expression(istream& is) {
00086 CRITERIUM crit = parse_criterium(is);
00087 if (crit == NONE)
00088 return false;
00089 criteria_.insert(crit);
00090 string pattern;
00091 if (!getline(is,pattern))
00092 return false;
00093
00094 if (pattern.size()) {
00095 string::size_type n0(pattern.find_first_not_of(" \t"));
00096 if (n0)
00097 pattern.erase(0,n0);
00098 if (pattern.size()) {
00099 string::size_type n1(pattern.find_last_not_of(" \t"));
00100 if (n1<(pattern.size()-1))
00101 pattern.erase(n1+1);
00102 }
00103 }
00104 if (pattern.size()==0)
00105 return false;
00106 switch (crit) {
00107 case DATE: {
00108 DatePattern dp;
00109 if (!dp.parse(pattern))
00110 return false;
00111 return new DateExpression(dp);
00112 }
00113 break;
00114 case DOMAIN: {
00115 Domain d;
00116 if (!d.parse(pattern))
00117 return false;
00118 return new DomainExpression(d);
00119 }
00120 break;
00121 case PATH: {
00122 Path p;
00123 if (!p.parse(pattern))
00124 return false;
00125 return new PathExpression(p);
00126 }
00127 break;
00128 default: return false;
00129 }
00130 }
00131
00132 bool
00133 Configuration::parse_exclude(istream& is) {
00134 Expression* e(parse_expression(is));
00135 if (e) {
00136 add_expression(new NotExpression(e));
00137 return true;
00138 }
00139 return false;
00140 }
00141
00142 Configuration::CRITERIUM
00143 Configuration::parse_criterium(istream& is) {
00144 string word;
00145 if (is >> word) {
00146 if (word=="path")
00147 return PATH;
00148 else if (word=="date")
00149 return DATE;
00150 else if (word=="domain")
00151 return DOMAIN;
00152 else
00153 return NONE;
00154 }
00155 return NONE;
00156 }
00157
00158 bool
00159 Configuration::parse_levels(istream& is,set<unsigned int>& levels) {
00160 levels.clear();
00161 string line;
00162 if (!getline(is,line))
00163 return false;
00164 const char* cline(line.c_str());
00165 const char* start(0);
00166
00167 char* end(const_cast<char*>(cline));
00168
00169 while (start!=end) {
00170 start = end;
00171 long l = strtol(start,&end,10);
00172 if (start!=end) {
00173 if (l<0)
00174 return false;
00175 unsigned int u1(static_cast<unsigned int>(l));
00176 levels.insert(u1);
00177 if (*end=='-') {
00178 start = end+1;
00179 if (*start=='\0')
00180 return false;
00181 long l2 = strtol(start,&end,10);
00182 if (start==end)
00183 return false;
00184 if (l2<0)
00185 return false;
00186 unsigned int u2(static_cast<unsigned int>(l2));
00187 for (unsigned int u=u1+1; u<=u2; ++u)
00188 levels.insert(u);
00189 }
00190 }
00191 }
00192 return true;
00193 }
00194
00195 ostream&
00196 operator<<(ostream& os,const Configuration& conf) {
00197 os << "format " << conf.format() << " ";
00198 copy(conf.levels().begin(),conf.levels().end(),ostream_iterator<unsigned int>(os," "));
00199 os << "\n";
00200 if (conf.select())
00201 os << *(conf.select());
00202 return os;
00203 }
00204
00205 ostream&
00206 operator<<(ostream& os,const Configuration::CRITERIUM& c) {
00207 switch (c) {
00208 case Configuration::DATE: os << "date"; break;
00209 case Configuration::DOMAIN: os << "domain"; break;
00210 case Configuration::PATH: os << "path"; break;
00211 case Configuration::NONE: os << "none"; break;
00212 default: os << "ERROR!!!"; break;
00213 }
00214 return os;
00215 }