]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_4.cpp | |
15 | * VERSION see <boost/version.hpp> | |
16 | * DESCRIPTION: regex_grep example 4: searches a cpp file for class definitions, | |
17 | * using a C++ Builder closure as a callback. | |
18 | */ | |
19 | ||
20 | #ifdef __BORLANDC__ | |
21 | ||
b32b8144 | 22 | #include <boost/regex.hpp> |
7c673cae FG |
23 | #include <string> |
24 | #include <map> | |
7c673cae FG |
25 | #include <functional> |
26 | ||
27 | // purpose: | |
28 | // takes the contents of a file in the form of a string | |
29 | // and searches for all the C++ class definitions, storing | |
30 | // their locations in a map of strings/int's | |
31 | ||
32 | typedef std::map<std::string, int, std::less<std::string> > map_type; | |
33 | ||
34 | const char* re = | |
35 | // possibly leading whitespace: | |
36 | "^[[:space:]]*" | |
37 | // possible template declaration: | |
38 | "(template[[:space:]]*<[^;:{]+>[[:space:]]*)?" | |
39 | // class or struct: | |
40 | "(class|struct)[[:space:]]*" | |
41 | // leading declspec macros etc: | |
42 | "(" | |
43 | "\\<\\w+\\>" | |
44 | "(" | |
45 | "[[:blank:]]*\\([^)]*\\)" | |
46 | ")?" | |
47 | "[[:space:]]*" | |
48 | ")*" | |
49 | // the class name | |
50 | "(\\<\\w*\\>)[[:space:]]*" | |
51 | // template specialisation parameters | |
52 | "(<[^;:{]+>)?[[:space:]]*" | |
53 | // terminate in { or : | |
54 | "(\\{|:[^;\\{()]*\\{)"; | |
55 | ||
56 | ||
57 | class class_index | |
58 | { | |
59 | boost::regex expression; | |
60 | map_type index; | |
61 | std::string::const_iterator base; | |
62 | typedef boost::match_results<std::string::const_iterator> arg_type; | |
63 | ||
64 | bool grep_callback(const boost::match_results<std::string::const_iterator>& what); | |
65 | public: | |
66 | map_type& get_map() { return index; } | |
67 | typedef bool (__closure* grep_callback_type)(const arg_type&); | |
68 | void IndexClasses(const std::string& file); | |
69 | class_index() | |
70 | : index(), | |
71 | expression(re) | |
72 | {} | |
73 | }; | |
74 | ||
75 | bool class_index::grep_callback(const boost::match_results<std::string::const_iterator>& what) | |
76 | { | |
77 | // what[0] contains the whole string | |
78 | // what[5] contains the class name. | |
79 | // what[6] contains the template specialisation if any. | |
80 | // add class name and position to map: | |
81 | index[std::string(what[5].first, what[5].second) + std::string(what[6].first, what[6].second)] = | |
82 | what[5].first - base; | |
83 | return true; | |
84 | } | |
85 | ||
86 | void class_index::IndexClasses(const std::string& file) | |
87 | { | |
88 | std::string::const_iterator start, end; | |
89 | start = file.begin(); | |
90 | end = file.end(); | |
91 | base = start; | |
92 | class_index::grep_callback_type cl = &(this->grep_callback); | |
93 | boost::regex_grep(cl, | |
94 | start, | |
95 | end, | |
96 | expression); | |
97 | } | |
98 | ||
99 | ||
100 | #include <fstream> | |
101 | #include <iostream> | |
102 | ||
103 | using namespace std; | |
104 | ||
105 | void load_file(std::string& s, std::istream& is) | |
106 | { | |
107 | s.erase(); | |
108 | if(is.bad()) return; | |
109 | s.reserve(is.rdbuf()->in_avail()); | |
110 | char c; | |
111 | while(is.get(c)) | |
112 | { | |
113 | if(s.capacity() == s.size()) | |
114 | s.reserve(s.capacity() * 3); | |
115 | s.append(1, c); | |
116 | } | |
117 | } | |
118 | ||
119 | int main(int argc, const char** argv) | |
120 | { | |
121 | std::string text; | |
122 | for(int i = 1; i < argc; ++i) | |
123 | { | |
124 | cout << "Processing file " << argv[i] << endl; | |
125 | std::ifstream fs(argv[i]); | |
126 | load_file(text, fs); | |
127 | fs.close(); | |
128 | class_index i; | |
129 | i.IndexClasses(text); | |
130 | cout << i.get_map().size() << " matches found" << endl; | |
131 | map_type::iterator c, d; | |
132 | c = i.get_map().begin(); | |
133 | d = i.get_map().end(); | |
134 | while(c != d) | |
135 | { | |
136 | cout << "class \"" << (*c).first << "\" found at index: " << (*c).second << endl; | |
137 | ++c; | |
138 | } | |
139 | } | |
140 | return 0; | |
141 | } | |
142 | ||
143 | #else // __BORLANDC__ | |
144 | ||
145 | int main() | |
146 | { | |
147 | return 0; | |
148 | } | |
149 | ||
150 | ||
151 | #endif | |
152 | ||
153 | ||
154 | ||
155 |