Advertisement
Guest User

debug_position

a guest
Nov 7th, 2012
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.53 KB | None | 0 0
  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, std::string const& pos );
  22.     };
  23.  
  24.     static bool report_impl_base( parser_debugger*, char const* pname, char const* msg, std::string const& pos,
  25.         std::ostream& os, size_t line_size, size_t pname_len, size_t msg_len )
  26.     {
  27.         size_t n = strlen( msg );
  28.         std::string pad;
  29.         if( n < msg_len ) pad.assign( (msg_len - n) / 2, ' ' );
  30.  
  31.         std::ios_base::fmtflags f = os.flags();
  32.         os.flags( f | std::ios_base::left );
  33.         os << std::setw(pname_len) << pname
  34.             << '(' << pad << std::setw(msg_len - pad.size()) << msg << "): ";
  35.         os.flags( f );
  36.  
  37.         bool sp = false;
  38.         std::size_t cnt = (std::max<size_t>)(strlen(pname), pname_len) + (std::max<size_t>)(n, msg_len) + 4;
  39.  
  40.         for( auto i = pos.begin(); i != pos.end(); i++ ) {
  41.             char c = *i;
  42.             if( ::isspace(c) ) {
  43.                 if( sp ) continue;
  44.                 sp = true;
  45.                 c = ' ';
  46.             } else {
  47.                 sp = false;
  48.             }
  49.  
  50.             if( cnt++ >= line_size ) {
  51.                 os << "...";
  52.                 break;
  53.             } else {
  54.                 os << c;
  55.             }
  56.         }
  57.         os << std::endl;
  58.         return true;
  59.     }
  60.     static bool report_impl( parser_debugger* pd, char const* pname, char const* msg, std::string const& pos ) {
  61.         return report_impl_base( pd, pname, msg, pos, std::clog, 100, 20, 10 );
  62.     }
  63.     static parser_debugger& default_parser_debugger() {
  64.         static parser_debugger res = { {&report_impl} };
  65.         return res;
  66.     }
  67.  
  68.     BOOST_SPIRIT_TERMINAL_EX( debug_position );
  69.     struct debug_position_parser : qi::primitive_parser<debug_position_parser> {
  70.         debug_position_parser( parser_debugger* pdebugger, char const* pname, char const* msg )
  71.             : pdebugger_( pdebugger ), pname_( pname ), msg_( msg ) {}
  72.  
  73.         template< typename ContextT, typename IteratorT >
  74.         struct attribute { typedef spirit::unused_type  type; };
  75.  
  76.         template< typename IteratorT, typename ContextT, typename SkipperT, typename AttributeT >
  77.         bool parse( IteratorT& first, IteratorT const& last, ContextT& context,
  78.             SkipperT const& skipper, AttributeT& attr ) const
  79.         {
  80.             typedef std::iterator_traits<IteratorT>::value_type char_type;
  81.             typedef std::basic_string<char_type>    string_type;
  82.  
  83.             qi::skip_over( first, last, skipper );
  84.             if( !pdebugger_ ) return true;
  85.  
  86.             pdebugger_->report( pdebugger_, pname_, msg_,
  87.                 boost::locale::conv::utf_to_utf<char>(string_type(first, last)) );
  88.  
  89.             return true;
  90.         }
  91.  
  92.         template< class ContextT >
  93.         spirit::info what( ContextT& context ) const {
  94.             return spirit::info( "debug_position", expression_ );
  95.         }
  96.  
  97.         char const* pname_;
  98.         char const* msg_;
  99.         parser_debugger* pdebugger_;
  100.     };
  101.  
  102. }
  103.  
  104. namespace boost { namespace spirit {
  105.  
  106.     template<>
  107.     struct use_terminal<qi::domain, mbl::tag::debug_position>
  108.         : mpl::true_ {};    // enable debug_position
  109.     template< typename A0, typename A1, typename A2 >
  110.     struct use_terminal<qi::domain,
  111.         terminal_ex<mbl::tag::debug_position, fusion::vector3<A0, A1, A2> >
  112.     > : is_convertible<A0, mbl::parser_debugger*> {};   // enable debug_position( debugger, name, pos )
  113.     template<>
  114.     struct use_lazy_terminal<qi::domain, mbl::tag::debug_position, 3 /*arity*/>
  115.         : mpl::true_ {};    // enable lazy support for debug_position
  116.  
  117.     namespace qi {
  118.  
  119.         template< typename A0, typename A1, typename A2, typename ModifiersT >
  120.         struct make_primitive<
  121.             terminal_ex<mbl::tag::debug_position, fusion::vector3<A0, A1, A2> >, ModifiersT >
  122.         {
  123.             typedef mbl::debug_position_parser result_type;
  124.  
  125.             template< typename TerminalT >
  126.             result_type operator()( TerminalT const& term, unused_type ) const {
  127.                 return result_type( fusion::at_c<0>(term.args), fusion::at_c<1>(term.args), fusion::at_c<2>(term.args) );
  128.             }
  129.         };
  130.  
  131.     }
  132.  
  133. } }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement