regex_iterator_example.cpp 2.9 KB

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