1 /* 2 * 3 * Copyright (c) 1998-2002 4 * John Maddock 5 * 6 * Use, modification and distribution are subject to the 7 * Boost Software License, Version 1.0. (See accompanying file 8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9 * 10 */ 11 12 /* 13 * LOCATION: see http://www.boost.org for most recent version. 14 * FILE regex_grep_example_2.cpp 15 * VERSION see <boost/version.hpp> 16 * DESCRIPTION: regex_grep example 2: searches a cpp file for class definitions, 17 * using a global callback function. 18 */ 19 20 #include <boost/regex.hpp> 21 #include <string> 22 #include <map> 23 #include <boost/regex.hpp> 24 25 // purpose: 26 // takes the contents of a file in the form of a string 27 // and searches for all the C++ class definitions, storing 28 // their locations in a map of strings/int's 29 30 typedef std::map<std::string, std::string::difference_type, std::less<std::string> > map_type; 31 32 const char* re = 33 // possibly leading whitespace: 34 "^[[:space:]]*" 35 // possible template declaration: 36 "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" 37 // class or struct: 38 "(class|struct)[[:space:]]*" 39 // leading declspec macros etc: 40 "(" 41 "\\<\\w+\\>" 42 "(" 43 "[[:blank:]]*\\([^)]*\\)" 44 ")?" 45 "[[:space:]]*" 46 ")*" 47 // the class name 48 "(\\<\\w*\\>)[[:space:]]*" 49 // template specialisation parameters 50 "(<[^;:{]+>)?[[:space:]]*" 51 // terminate in { or : 52 "(\\{|:[^;\\{()]*\\{)"; 53 54 55 boost::regex expression(re); 56 map_type class_index; 57 std::string::const_iterator base; 58 grep_callback(const boost::match_results<std::string::const_iterator> & what)59 bool grep_callback(const boost::match_results<std::string::const_iterator>& what) 60 { 61 // what[0] contains the whole string 62 // what[5] contains the class name. 63 // what[6] contains the template specialisation if any. 64 // add class name and position to map: 65 class_index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = 66 what[5].first - base; 67 return true; 68 } 69 IndexClasses(const std::string & file)70 void IndexClasses(const std::string& file) 71 { 72 std::string::const_iterator start, end; 73 start = file.begin(); 74 end = file.end(); 75 base = start; 76 boost::regex_grep(grep_callback, start, end, expression); 77 } 78 79 #include <fstream> 80 #include <iostream> 81 82 using namespace std; 83 load_file(std::string & s,std::istream & is)84 void load_file(std::string& s, std::istream& is) 85 { 86 s.erase(); 87 if(is.bad()) return; 88 s.reserve(static_cast<std::string::size_type>(is.rdbuf()->in_avail())); 89 char c; 90 while(is.get(c)) 91 { 92 if(s.capacity() == s.size()) 93 s.reserve(s.capacity() * 3); 94 s.append(1, c); 95 } 96 } 97 main(int argc,const char ** argv)98 int main(int argc, const char** argv) 99 { 100 std::string text; 101 for(int i = 1; i < argc; ++i) 102 { 103 cout << "Processing file " << argv[i] << endl; 104 std::ifstream fs(argv[i]); 105 load_file(text, fs); 106 fs.close(); 107 IndexClasses(text); 108 cout << class_index.size() << " matches found" << endl; 109 map_type::iterator c, d; 110 c = class_index.begin(); 111 d = class_index.end(); 112 while(c != d) 113 { 114 cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; 115 ++c; 116 } 117 class_index.erase(class_index.begin(), class_index.end()); 118 } 119 return 0; 120 } 121 122 123 124