Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

debug_position

By: a guest on Nov 7th, 2012  |  syntax: C++  |  size: 4.56 KB  |  views: 33  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #if (defined(_DEBUG) && !defined(MBLQI_DONT_DEBUG_RULES)) || defined(MBLQI_DEBUG_RULES)
  2. #       define MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )         \
  3.         ::mbl::debug_position( pdbg, pname, ppos )
  4. #       define MBL_QI_DEBUG_PARSER_( pdbg, pname, ppos )        MBL_QI_DEBUG_PARSER( pdbg, pname, ppos ) >>
  5. #       define _MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )        >> MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )
  6. #else
  7. #       define MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )        
  8. #       define MBL_QI_DEBUG_PARSER_( pdbg, pname, ppos )       
  9. #       define _MBL_QI_DEBUG_PARSER( pdbg, pname, ppos )       
  10. #endif
  11.  
  12. #define MBL_QI_DEBUG_MSG_START                                          "<START>"
  13. #define MBL_QI_DEBUG_MSG_END                                            "<END>"
  14. #define MBL_QI_DEBUG_PARSER_START( pdbg, pname )        MBL_QI_DEBUG_PARSER_( pdbg, pname, MBL_QI_DEBUG_MSG_START )
  15. #define MBL_QI_DEBUG_PARSER_END( pdbg, pname )          _MBL_QI_DEBUG_PARSER( pdbg, pname, MBL_QI_DEBUG_MSG_END )
  16.  
  17. namespace mbl {
  18.  
  19.         struct parser_debugger {
  20.                 // could be virtual, but I want my type to be POD
  21.                 bool (*report)( parser_debugger*, char const* parserName, char const* msg,
  22.                     std::string const& pos );
  23.         };
  24.  
  25.         static bool report_impl_base( parser_debugger*, char const* pname,
  26.             char const* msg, std::string const& pos, std::ostream& os, size_t line_size,
  27.             size_t pname_len, size_t msg_len )
  28.         {
  29.                 size_t n = strlen( msg );
  30.                 std::string pad;
  31.                 if( n < msg_len ) pad.assign( (msg_len - n) / 2, ' ' );
  32.  
  33.                 std::ios_base::fmtflags f = os.flags();
  34.                 os.flags( f | std::ios_base::left );
  35.                 os << std::setw(pname_len) << pname
  36.                         << '(' << pad << std::setw(msg_len - pad.size()) << msg << "): ";
  37.                 os.flags( f );
  38.  
  39.                 bool sp = false;
  40.                 std::size_t cnt = (std::max<size_t>)(strlen(pname), pname_len) +
  41.                     (std::max<size_t>)(n, msg_len) + 4;
  42.  
  43.                 for( auto i = pos.begin(); i != pos.end(); i++ ) {
  44.                         char c = *i;
  45.                         if( ::isspace(c) ) {
  46.                                 if( sp ) continue;
  47.                                 sp = true;
  48.                                 c = ' ';
  49.                         } else {
  50.                                 sp = false;
  51.                         }
  52.  
  53.                         if( cnt++ >= line_size ) {
  54.                                 os << "...";
  55.                                 break;
  56.                         } else {
  57.                                 os << c;
  58.                         }
  59.                 }
  60.                 os << std::endl;
  61.                 return true;
  62.         }
  63.         static bool report_impl( parser_debugger* pd, char const* pname, char const* msg,
  64.                 std::string const& pos )
  65.         {
  66.                 return report_impl_base( pd, pname, msg, pos, std::clog, 100, 20, 10 );
  67.         }
  68.         static parser_debugger& default_parser_debugger() {
  69.                 static parser_debugger res = { {&report_impl} };
  70.                 return res;
  71.         }
  72.  
  73.         BOOST_SPIRIT_TERMINAL_EX( debug_position );
  74.         struct debug_position_parser : qi::primitive_parser<debug_position_parser> {
  75.                 debug_position_parser( parser_debugger* pdebugger, char const* pname, char const* msg )
  76.                         : pdebugger_( pdebugger ), pname_( pname ), msg_( msg ) {}
  77.  
  78.                 template< typename ContextT, typename IteratorT >
  79.                 struct attribute { typedef spirit::unused_type  type; };
  80.  
  81.                 template< typename IteratorT, typename ContextT, typename SkipperT, typename AttributeT >
  82.                 bool parse( IteratorT& first, IteratorT const& last, ContextT& context,
  83.                         SkipperT const& skipper, AttributeT& attr ) const
  84.                 {
  85.                         typedef std::iterator_traits<IteratorT>::value_type char_type;
  86.                         typedef std::basic_string<char_type>    string_type;
  87.  
  88.                         qi::skip_over( first, last, skipper );
  89.                         if( !pdebugger_ ) return true;
  90.  
  91.                         pdebugger_->report( pdebugger_, pname_, msg_,
  92.                                 boost::locale::conv::utf_to_utf<char>(string_type(first, last)) );
  93.  
  94.                         return true;
  95.                 }
  96.  
  97.                 template< class ContextT >
  98.                 spirit::info what( ContextT& context ) const {
  99.                         return spirit::info( "debug_position", expression_ );
  100.                 }
  101.  
  102.                 char const* pname_;
  103.                 char const* msg_;
  104.                 parser_debugger* pdebugger_;
  105.         };
  106.  
  107. }
  108.  
  109. namespace boost { namespace spirit {
  110.  
  111.         template<>
  112.         struct use_terminal<qi::domain, mbl::tag::debug_position>
  113.                 : mpl::true_ {};        // enable debug_position
  114.         template< typename A0, typename A1, typename A2 >
  115.         struct use_terminal<qi::domain,
  116.                 terminal_ex<mbl::tag::debug_position, fusion::vector3<A0, A1, A2> >
  117.         > : is_convertible<A0, mbl::parser_debugger*> {}; // enable debug_position( debugger, name, pos )
  118.         template<>
  119.         struct use_lazy_terminal<qi::domain, mbl::tag::debug_position, 3 /*arity*/>
  120.                 : mpl::true_ {};        // enable lazy support for debug_position
  121.  
  122.         namespace qi {
  123.  
  124.                 template< typename A0, typename A1, typename A2, typename ModifiersT >
  125.                 struct make_primitive<
  126.                         terminal_ex<mbl::tag::debug_position, fusion::vector3<A0, A1, A2> >, ModifiersT >
  127.                 {
  128.                         typedef mbl::debug_position_parser result_type;
  129.  
  130.                         template< typename TerminalT >
  131.                         result_type operator()( TerminalT const& term, unused_type ) const {
  132.                                 return result_type( fusion::at_c<0>(term.args),
  133.                                         fusion::at_c<1>(term.args), fusion::at_c<2>(term.args) );
  134.                         }
  135.                 };
  136.  
  137.         }
  138.  
  139. } }