emit_custom_line_directives.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. Sample demonstrating the usage of advanced preprocessor hooks.
  4. http://www.boost.org/
  5. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  6. Software License, Version 1.0. (See accompanying file
  7. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #include <iostream>
  10. #include <fstream>
  11. #include <string>
  12. #include <vector>
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // Include Wave itself
  15. #include <boost/wave.hpp>
  16. ///////////////////////////////////////////////////////////////////////////////
  17. // Include the lexer stuff
  18. #include <boost/wave/cpplexer/cpp_lex_token.hpp> // token class
  19. #include <boost/wave/cpplexer/cpp_lex_iterator.hpp> // lexer class
  20. #include "emit_custom_line_directives.hpp"
  21. ///////////////////////////////////////////////////////////////////////////////
  22. // Main entry point
  23. //
  24. // This sample shows how to use the emit_line_directive preprocessing hooks
  25. // to customize the format of any generated #line directive. The sample will
  26. // emit #line directives formatted compatible with those generated by gcc:
  27. //
  28. // # <lineno> <rel_file_name>
  29. //
  30. int main(int argc, char *argv[])
  31. {
  32. if (2 != argc) {
  33. std::cerr << "Usage: emit_custom_line_directives infile" << std::endl;
  34. return -1;
  35. }
  36. // current file position is saved for exception handling
  37. boost::wave::util::file_position_type current_position;
  38. try {
  39. // Open and read in the specified input file.
  40. std::ifstream instream(argv[1]);
  41. std::string instring;
  42. if (!instream.is_open()) {
  43. std::cerr << "Could not open input file: " << argv[1] << std::endl;
  44. return -2;
  45. }
  46. instream.unsetf(std::ios::skipws);
  47. instring = std::string(std::istreambuf_iterator<char>(instream.rdbuf()),
  48. std::istreambuf_iterator<char>());
  49. // The template boost::wave::cpplexer::lex_token<> is the token type to be
  50. // used by the Wave library.
  51. typedef boost::wave::cpplexer::lex_token<> token_type;
  52. // The template boost::wave::cpplexer::lex_iterator<> is the lexer type to
  53. // be used by the Wave library.
  54. typedef boost::wave::cpplexer::lex_iterator<token_type> lex_iterator_type;
  55. // This is the resulting context type to use. The first template parameter
  56. // should match the iterator type to be used during construction of the
  57. // corresponding context object (see below).
  58. typedef boost::wave::context<std::string::iterator, lex_iterator_type,
  59. boost::wave::iteration_context_policies::load_file_to_string,
  60. emit_custom_line_directives_hooks
  61. > context_type;
  62. // The preprocessor iterator shouldn't be constructed directly. It is
  63. // to be generated through a wave::context<> object. This wave:context<>
  64. // object additionally may be used to initialize and define different
  65. // parameters of the actual preprocessing (not done here).
  66. //
  67. // The preprocessing of the input stream is done on the fly behind the
  68. // scenes during iteration over the context_type::iterator_type stream.
  69. context_type ctx (instring.begin(), instring.end(), argv[1]);
  70. ctx.set_language(boost::wave::enable_long_long(ctx.get_language()));
  71. ctx.set_language(boost::wave::enable_preserve_comments(ctx.get_language()));
  72. ctx.set_language(boost::wave::enable_prefer_pp_numbers(ctx.get_language()));
  73. // analyze the input file, print out the preprocessed tokens
  74. context_type::iterator_type first = ctx.begin();
  75. context_type::iterator_type last = ctx.end();
  76. while (first != last) {
  77. current_position = (*first).get_position();
  78. std::cout << (*first).get_value();
  79. ++first;
  80. }
  81. }
  82. catch (boost::wave::cpp_exception const& e) {
  83. // some preprocessing error
  84. std::cerr
  85. << e.file_name() << "(" << e.line_no() << "): "
  86. << e.description() << std::endl;
  87. return 2;
  88. }
  89. catch (std::exception const& e) {
  90. // use last recognized token to retrieve the error position
  91. std::cerr
  92. << current_position.get_file()
  93. << "(" << current_position.get_line() << "): "
  94. << "exception caught: " << e.what()
  95. << std::endl;
  96. return 3;
  97. }
  98. catch (...) {
  99. // use last recognized token to retrieve the error position
  100. std::cerr
  101. << current_position.get_file()
  102. << "(" << current_position.get_line() << "): "
  103. << "unexpected exception caught." << std::endl;
  104. return 4;
  105. }
  106. return 0;
  107. }