Changeset 516
- Timestamp:
- Dec 9, 2007, 8:58:54 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Configuration.cc
r515 r516 65 65 Configuration::codon(std::string file_name) const 66 66 { 67 if (const std::pair<std::string,std::string>* dict=dictionary(file_name)) 68 try { 69 file_name = translate(file_name, *dict); 70 } 71 catch (std::runtime_error& e) { 72 std::stringstream mess; 73 mess << "svndigest: invalid config file: " 74 << "expression " << dict->second << " is invalid"; 75 if (e.what()[0]) 76 mess << "because " << e.what() << " is a too large."; 77 else 78 mess << "."; 79 throw std::runtime_error(mess.str()); 80 } 67 81 for (String2Codons::const_iterator i(string2codons_.begin()); 68 82 i!=string2codons_.end(); ++i) { … … 82 96 83 97 98 const std::pair<std::string,std::string>* 99 Configuration::dictionary(std::string lhs) const 100 { 101 for (size_t i=0; i<dictionary_.size(); ++i) 102 if (svndigest::equal(lhs.begin(), lhs.end(), 103 dictionary_[i].first.begin(), 104 dictionary_[i].first.end())) 105 return &dictionary_[i]; 106 return NULL; 107 } 108 109 84 110 bool Configuration::equal_false(const std::string& str) const 85 111 { … … 108 134 109 135 bool parsing_found=false; 136 bool dictionary_found=false; 110 137 std::string line; 111 138 std::string section; … … 178 205 mess << "svndigest: invalid config file\n" 179 206 << "line: `" << line << "' is invalid.\n" 180 << "clashes with previous given file -name-pattern: ";207 << "clashes with previous given file name pattern: "; 181 208 // find previous file-name-pattern 182 209 for (String2Codons::const_iterator i(string2codons_.begin()); … … 210 237 } 211 238 } 239 else if (section == "file-name-dictionary") { 240 if (!dictionary_found) { 241 dictionary_found=true; 242 // clearing the default setting 243 dictionary_.clear(); 244 } 245 246 if (const std::pair<std::string, std::string>* entry=dictionary(lhs)) { 247 std::stringstream mess; 248 mess << "svndigest: invalid config file\n" 249 << "line: `" << line << "' is invalid.\n" 250 << "clashes with previous given file name pattern: " 251 << "`" << entry->first << "'"; 252 throw std::runtime_error(mess.str()); 253 } 254 lhs = trim(lhs); 255 rhs = trim(rhs); 256 if (!lhs.empty() && !rhs.empty()) 257 dictionary_.push_back(std::make_pair(lhs, rhs)); 258 else if (!lhs.empty() || !rhs.empty()) { 259 std::stringstream mess; 260 mess << "svndigest: invalid config file\n" 261 << "line: `" << line << "' is invalid.\n"; 262 throw std::runtime_error(mess.str()); 263 } 264 } 212 265 } 213 266 } … … 225 278 { 226 279 return missing_copyright_warning_; 280 } 281 282 283 std::string 284 Configuration::translate(const std::string& str, 285 const std::pair<std::string, std::string>& dic) const 286 { 287 assert(svndigest::equal(str.begin(), str.end(), 288 dic.first.begin(), dic.first.end())); 289 std::string res; 290 std::vector<std::string> vec; 291 regexp(str.begin(), str.end(), dic.first.begin(), dic.first.end(), vec); 292 for (std::string::const_iterator i(dic.second.begin()); 293 i!=dic.second.end(); ++i) { 294 if (*i == '$') { 295 std::stringstream ss(std::string(i, dic.second.end())); 296 size_t n = 0; 297 ss >> n; 298 if (n>vec.size()){ 299 std::stringstream mess; 300 mess << n; 301 throw std::runtime_error(mess.str()); 302 } 303 if (n) { 304 res += vec[n-1]; 305 ++i; 306 if (n>9){ 307 ++i; 308 if (n>99) 309 ++i; 310 } 311 } 312 else 313 throw std::runtime_error(""); 314 } 315 else 316 res += *i; 317 } 318 319 return res; 227 320 } 228 321 -
trunk/lib/Configuration.h
r515 r516 96 96 97 97 void clear(void); 98 98 const std::pair<std::string,std::string>* dictionary(std::string lhs) const; 99 99 bool equal_false(const std::string&) const; 100 100 bool equal_true(const std::string&) const; 101 std::string trans_end_code(std::string) const;102 std::string trans_beg_code(std::string) const;103 101 void set_default(void); 102 /** 103 Translate string \a str using dictionary \a dict 104 105 \note \a str must be equal to d.first, or behavior is unspecified. 106 107 \throw if a '$' character is not followed by a positive integer 108 that is not larger than number of wildcards in dictionary \a d. 109 */ 110 std::string translate(const std::string& str, 111 const std::pair<std::string, std::string>& d) const; 104 112 105 113 static Configuration* instance_; … … 123 131 std::ostream& operator<<(std::ostream&, const Configuration&); 124 132 133 /** 134 If first character is '\n' replace it with "<NEWLINE>" 135 */ 136 std::string trans_end_code(std::string); 137 138 /** 139 If last character is '\n' replace it with "<NEWLINE>" 140 */ 141 std::string trans_beg_code(std::string); 142 125 143 }} // end of namespace svndigest and namespace theplu 126 144 -
trunk/lib/Parser.cc
r514 r516 43 43 std::ifstream is(path.c_str()); 44 44 assert(is.good()); 45 // Ignore trailing '.in' in file names46 if (match_end(path.rbegin(), path.rend(), ".in"))47 path = path.substr(0, path.size()-3);48 45 const std::vector<std::pair<std::string, std::string> >* codon = 49 46 Configuration::instance().codon(path); -
trunk/lib/utility.cc
r514 r516 24 24 #include "utility.h" 25 25 26 #include <cassert> 26 27 #include <cerrno> 27 28 #include <cstdlib> … … 208 209 209 210 211 bool regexp(std::string::const_iterator first1, 212 std::string::const_iterator last1, 213 std::string::const_iterator first2, 214 std::string::const_iterator last2, 215 std::vector<std::string>& vec) 216 { 217 if (vec.empty()) 218 vec.push_back(""); 219 220 // first two cases when ranges are empty 221 if (first1==last1 && first2==last2){ 222 vec.pop_back(); 223 return true; 224 } 225 if (first1==last1 || first2==last2) 226 return false; 227 228 // then we take care of the real stuff 229 if (*first2 == '*'){ 230 // trying '*' to consume another character 231 vec.back().append(1, *first1); 232 if (regexp(first1+1, last1, first2, last2, vec) ) 233 return true; 234 assert(vec.back().size()); 235 vec.back().resize(vec.back().size()-1); 236 237 // stepping away from the '*' 238 vec.push_back(""); 239 if (regexp(first1, last1, first2+1, last2, vec)) 240 return true; 241 vec.pop_back(); 242 return false; 243 } 244 else if (*first2 == '?'){ 245 // eating a character 246 vec.back() = std::string(first1, first1+1); 247 vec.push_back(""); 248 if (regexp(first1+1, last1, first2+1, last2, vec) ) 249 return true; 250 vec.pop_back(); 251 // ? interpreted as zero characters 252 vec.back() = ""; 253 vec.push_back(""); 254 if (regexp(first1, last1, first2+1, last2, vec) ) 255 return true; 256 vec.pop_back(); 257 return false; 258 } 259 if (*first1 != *first2) 260 return false; 261 return regexp(++first1, last1, ++first2, last2, vec); 262 } 263 264 210 265 void replace(std::string& str, std::string old_str, std::string new_str) 211 266 { -
trunk/lib/utility.h
r514 r516 150 150 /// 151 151 std::string pwd(void); 152 153 /** 154 \return true if first range match second range 155 156 Second range may contain wildcards (such as '*' and '?'), in 157 which case vector \a vec is filled with the corresponding strings 158 in first range. The algorithm is greedy, i.e., wildcard * is will 159 consume as many charcters as possible. 160 161 \note \a vec is supposed to be empty 162 */ 163 bool regexp(std::string::const_iterator first1, 164 std::string::const_iterator end1, 165 std::string::const_iterator first2, 166 std::string::const_iterator end2, 167 std::vector<std::string>& vec); 152 168 153 169 /** -
trunk/test/repo/db/current
r513 r516 1 5 51l 11 56 1l 1 -
trunk/test/utility_test.cc
r507 r516 24 24 #include "utility.h" 25 25 26 #include <algorithm> 27 #include <iterator> 26 28 #include <iostream> 27 29 #include <string> … … 29 31 bool test_hex(int, u_int, std::string); 30 32 bool test_equal(bool, std::string, std::string); 33 bool test_regexp(bool, std::string, std::string, 34 const std::vector<std::string>&); 31 35 32 36 int main(const int argc,const char* argv[]) … … 43 47 ok &= test_equal(true,"peter", "p*"); 44 48 ok &= test_equal(false,"peter", "p*j"); 49 50 std::vector<std::string> vec; 51 ok &= test_regexp(true,"abcde", "abcde", vec); 52 vec.push_back(""); 53 ok &= test_regexp(true,"abcde", "abcd?e", vec); 54 vec[0]="c"; 55 ok &= test_regexp(true,"abcde", "ab?de", vec); 56 vec[0] = "bcd"; 57 ok &= test_regexp(true,"abcde", "a*e", vec); 58 vec.push_back(""); 59 ok &= test_regexp(true,"abcddf", "a*d*f", vec); 60 vec[0] = "bc"; 61 vec[1] = "ef"; 62 ok &= test_regexp(true,"abcdefg", "a*d*g", vec); 63 vec.push_back(""); 64 ok &= test_regexp(true,"abcdefg", "a*d*?g", vec); 45 65 46 66 if (ok) … … 69 89 } 70 90 91 bool test_regexp(bool ans, std::string a, std::string b, 92 const std::vector<std::string>& vec) 93 { 94 using namespace theplu::svndigest; 95 std::vector<std::string> v; 96 bool res = regexp(a.begin(), a.end(), b.begin(), b.end(), v); 97 if (res!=ans || v!=vec) { 98 std::cerr << "regexp(" << a << ", " << b << ") results " 99 << res << ". Expected " << ans << "\n" 100 << "resulting vector:\n"; 101 std::copy(v.begin(), v.end(), 102 std::ostream_iterator<std::string>(std::cerr, "\n")); 103 std::cerr << "expected:\n"; 104 std::copy(vec.begin(), vec.end(), 105 std::ostream_iterator<std::string>(std::cerr, "\n")); 106 return false; 107 } 108 return true; 109 110 }
Note: See TracChangeset
for help on using the changeset viewer.