regex_grep_example_1.cpp 3.2 KB

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