simple_trace.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright (c) 2001-2011 Hartmut Kaiser
  2. // Copyright (c) 2001-2011 Joel de Guzman
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #if !defined(BOOST_SPIRIT_KARMA_SIMPLE_TRACE_APR_21_2010_0155PM)
  7. #define BOOST_SPIRIT_KARMA_SIMPLE_TRACE_APR_21_2010_0155PM
  8. #if defined(_MSC_VER)
  9. #pragma once
  10. #endif
  11. #include <boost/spirit/home/support/unused.hpp>
  12. #include <boost/spirit/home/karma/nonterminal/debug_handler_state.hpp>
  13. #include <boost/fusion/include/out.hpp>
  14. #include <iostream>
  15. // The stream to use for debug output
  16. #if !defined(BOOST_SPIRIT_DEBUG_OUT)
  17. #define BOOST_SPIRIT_DEBUG_OUT std::cerr
  18. #endif
  19. // number of tokens to print while debugging
  20. #if !defined(BOOST_SPIRIT_DEBUG_PRINT_SOME)
  21. #define BOOST_SPIRIT_DEBUG_PRINT_SOME 20
  22. #endif
  23. // number of spaces to indent
  24. #if !defined(BOOST_SPIRIT_DEBUG_INDENT)
  25. #define BOOST_SPIRIT_DEBUG_INDENT 2
  26. #endif
  27. namespace boost { namespace spirit { namespace karma
  28. {
  29. struct simple_trace
  30. {
  31. int& get_indent() const
  32. {
  33. static int indent = 0;
  34. return indent;
  35. }
  36. void print_indent() const
  37. {
  38. int n = get_indent();
  39. n *= BOOST_SPIRIT_DEBUG_INDENT;
  40. for (int i = 0; i != n; ++i)
  41. BOOST_SPIRIT_DEBUG_OUT << ' ';
  42. }
  43. template <typename Buffer>
  44. void print_some(char const* tag, Buffer const& buffer) const
  45. {
  46. print_indent();
  47. BOOST_SPIRIT_DEBUG_OUT << '<' << tag << '>' << std::flush;
  48. {
  49. std::ostreambuf_iterator<char> out(BOOST_SPIRIT_DEBUG_OUT);
  50. buffer.buffer_copy_to(out, BOOST_SPIRIT_DEBUG_PRINT_SOME);
  51. }
  52. BOOST_SPIRIT_DEBUG_OUT << "</" << tag << '>' << std::endl;
  53. }
  54. template <typename OutputIterator, typename Context, typename State
  55. , typename Buffer>
  56. void operator()(
  57. OutputIterator&, Context const& context
  58. , State state, std::string const& rule_name
  59. , Buffer const& buffer) const
  60. {
  61. switch (state)
  62. {
  63. case pre_generate:
  64. print_indent();
  65. ++get_indent();
  66. BOOST_SPIRIT_DEBUG_OUT
  67. << '<' << rule_name << '>' << std::endl;
  68. print_indent();
  69. ++get_indent();
  70. BOOST_SPIRIT_DEBUG_OUT << "<try>" << std::endl;;
  71. print_indent();
  72. BOOST_SPIRIT_DEBUG_OUT << "<attributes>";
  73. traits::print_attribute(
  74. BOOST_SPIRIT_DEBUG_OUT,
  75. context.attributes
  76. );
  77. BOOST_SPIRIT_DEBUG_OUT << "</attributes>" << std::endl;
  78. if (!fusion::empty(context.locals))
  79. {
  80. print_indent();
  81. BOOST_SPIRIT_DEBUG_OUT
  82. << "<locals>" << context.locals << "</locals>"
  83. << std::endl;
  84. }
  85. --get_indent();
  86. print_indent();
  87. BOOST_SPIRIT_DEBUG_OUT << "</try>" << std::endl;;
  88. break;
  89. case successful_generate:
  90. print_indent();
  91. ++get_indent();
  92. BOOST_SPIRIT_DEBUG_OUT << "<success>" << std::endl;
  93. print_some("result", buffer);
  94. if (!fusion::empty(context.locals))
  95. {
  96. print_indent();
  97. BOOST_SPIRIT_DEBUG_OUT
  98. << "<locals>" << context.locals << "</locals>"
  99. << std::endl;
  100. }
  101. --get_indent();
  102. print_indent();
  103. BOOST_SPIRIT_DEBUG_OUT << "</success>" << std::endl;
  104. --get_indent();
  105. print_indent();
  106. BOOST_SPIRIT_DEBUG_OUT
  107. << "</" << rule_name << '>' << std::endl;
  108. break;
  109. case failed_generate:
  110. print_indent();
  111. BOOST_SPIRIT_DEBUG_OUT << "<fail/>" << std::endl;
  112. --get_indent();
  113. print_indent();
  114. BOOST_SPIRIT_DEBUG_OUT
  115. << "</" << rule_name << '>' << std::endl;
  116. break;
  117. }
  118. }
  119. };
  120. }}}
  121. #endif