preprocess_pragma_output.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. Example demonstrating how to preprocess the token stream generated by a
  4. #pragma directive
  5. http://www.boost.org/
  6. Copyright (c) 2001-2010 Hartmut Kaiser. Distributed under the Boost
  7. 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. #include <iostream>
  11. #include <fstream>
  12. #include <string>
  13. #include <vector>
  14. ///////////////////////////////////////////////////////////////////////////////
  15. // Include Wave itself
  16. #include <boost/wave.hpp>
  17. ///////////////////////////////////////////////////////////////////////////////
  18. // Include the lexer stuff
  19. #include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class
  20. #include <boost/wave/cpplexer/cpp_lex_iterator.hpp> // lexer class
  21. ///////////////////////////////////////////////////////////////////////////////
  22. // Include special preprocessing hooks
  23. #include "preprocess_pragma_output.hpp"
  24. ///////////////////////////////////////////////////////////////////////////////
  25. // main entry point
  26. int main(int argc, char *argv[])
  27. {
  28. if (2 != argc) {
  29. std::cerr << "Usage: preprocess_pragma_output infile" << std::endl;
  30. return -1;
  31. }
  32. // current file position is saved for exception handling
  33. boost::wave::util::file_position_type current_position;
  34. try {
  35. // Open and read in the specified input file.
  36. std::ifstream instream(argv[1]);
  37. std::string instring;
  38. if (!instream.is_open()) {
  39. std::cerr << "Could not open input file: " << argv[1] << std::endl;
  40. return -2;
  41. }
  42. instream.unsetf(std::ios::skipws);
  43. instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
  44. std::istreambuf_iterator<char>());
  45. // The template boost::wave::cpplexer::lex_token<> is the token type to be
  46. // used by the Wave library.
  47. typedef boost::wave::cpplexer::lex_token<> token_type;
  48. // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to
  49. // be used by the Wave library.
  50. typedef boost::wave::cpplexer::lex_iterator<token_type> lex_iterator_type;
  51. // This is the resulting context type to use.
  52. typedef boost::wave::context<
  53. std::string::iterator, lex_iterator_type,
  54. boost::wave::iteration_context_policies::load_file_to_string,
  55. preprocess_pragma_output_hooks>
  56. context_type;
  57. // The preprocessor iterator shouldn't be constructed directly. It is
  58. // to be generated through a wave::context<> object. This wave:context<>
  59. // object is to be used additionally to initialize and define different
  60. // parameters of the actual preprocessing (not done here).
  61. //
  62. // The preprocessing of the input stream is done on the fly behind the
  63. // scenes during iteration over the context_type::iterator_type stream.
  64. context_type ctx (instring.begin(), instring.end(), argv[1]);
  65. // analyze the input file
  66. context_type::iterator_type first = ctx.begin();
  67. context_type::iterator_type last = ctx.end();
  68. while (first != last) {
  69. current_position = (*first).get_position();
  70. std::cout << (*first).get_value();
  71. ++first;
  72. }
  73. }
  74. catch (boost::wave::cpp_exception const& e) {
  75. // some preprocessing error
  76. std::cerr
  77. << e.file_name() << "(" << e.line_no() << "): "
  78. << e.description() << std::endl;
  79. return 2;
  80. }
  81. catch (std::exception const& e) {
  82. // use last recognized token to retrieve the error position
  83. std::cerr
  84. << current_position.get_file()
  85. << "(" << current_position.get_line() << "): "
  86. << "exception caught: " << e.what()
  87. << std::endl;
  88. return 3;
  89. }
  90. catch (...) {
  91. // use last recognized token to retrieve the error position
  92. std::cerr
  93. << current_position.get_file()
  94. << "(" << current_position.get_line() << "): "
  95. << "unexpected exception caught." << std::endl;
  96. return 4;
  97. }
  98. return 0;
  99. }