]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * | |
3 | * Copyright (c) 2003 | |
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_iterator_example_2.cpp | |
15 | * VERSION see <boost/version.hpp> | |
16 | * DESCRIPTION: regex_iterator example 2: searches a cpp file for class definitions, | |
17 | * using global data. | |
18 | */ | |
19 | ||
b32b8144 | 20 | #include <boost/regex.hpp> |
7c673cae FG |
21 | #include <string> |
22 | #include <map> | |
23 | #include <fstream> | |
24 | #include <iostream> | |
7c673cae FG |
25 | |
26 | using namespace std; | |
27 | ||
28 | // purpose: | |
29 | // takes the contents of a file in the form of a string | |
30 | // and searches for all the C++ class definitions, storing | |
31 | // their locations in a map of strings/int's | |
32 | ||
33 | typedef std::map<std::string, std::string::difference_type, std::less<std::string> > map_type; | |
34 | ||
35 | const char* re = | |
36 | // possibly leading whitespace: | |
37 | "^[[:space:]]*" | |
38 | // possible template declaration: | |
39 | "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" | |
40 | // class or struct: | |
41 | "(class|struct)[[:space:]]*" | |
42 | // leading declspec macros etc: | |
43 | "(" | |
44 | "\\<\\w+\\>" | |
45 | "(" | |
46 | "[[:blank:]]*\\([^)]*\\)" | |
47 | ")?" | |
48 | "[[:space:]]*" | |
49 | ")*" | |
50 | // the class name | |
51 | "(\\<\\w*\\>)[[:space:]]*" | |
52 | // template specialisation parameters | |
53 | "(<[^;:{]+>)?[[:space:]]*" | |
54 | // terminate in { or : | |
55 | "(\\{|:[^;\\{()]*\\{)"; | |
56 | ||
57 | ||
58 | boost::regex expression(re); | |
59 | map_type class_index; | |
60 | ||
61 | bool regex_callback(const boost::match_results<std::string::const_iterator>& what) | |
62 | { | |
63 | // what[0] contains the whole string | |
64 | // what[5] contains the class name. | |
65 | // what[6] contains the template specialisation if any. | |
66 | // add class name and position to map: | |
67 | class_index[what[5].str() + what[6].str()] = what.position(5); | |
68 | return true; | |
69 | } | |
70 | ||
71 | void load_file(std::string& s, std::istream& is) | |
72 | { | |
73 | s.erase(); | |
74 | if(is.bad()) return; | |
75 | s.reserve(static_cast<std::string::size_type>(is.rdbuf()->in_avail())); | |
76 | char c; | |
77 | while(is.get(c)) | |
78 | { | |
79 | if(s.capacity() == s.size()) | |
80 | s.reserve(s.capacity() * 3); | |
81 | s.append(1, c); | |
82 | } | |
83 | } | |
84 | ||
85 | int main(int argc, const char** argv) | |
86 | { | |
87 | std::string text; | |
88 | for(int i = 1; i < argc; ++i) | |
89 | { | |
90 | cout << "Processing file " << argv[i] << endl; | |
91 | std::ifstream fs(argv[i]); | |
92 | load_file(text, fs); | |
93 | fs.close(); | |
94 | // construct our iterators: | |
95 | boost::sregex_iterator m1(text.begin(), text.end(), expression); | |
96 | boost::sregex_iterator m2; | |
97 | std::for_each(m1, m2, ®ex_callback); | |
98 | // copy results: | |
99 | cout << class_index.size() << " matches found" << endl; | |
100 | map_type::iterator c, d; | |
101 | c = class_index.begin(); | |
102 | d = class_index.end(); | |
103 | while(c != d) | |
104 | { | |
105 | cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; | |
106 | ++c; | |
107 | } | |
108 | class_index.erase(class_index.begin(), class_index.end()); | |
109 | } | |
110 | return 0; | |
111 | } | |
112 | ||
113 | ||
114 |