00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00026
00045
00046
00047 #ifndef _CTTL_XTL_QUOTE_H_INCLUDED_
00048 #define _CTTL_XTL_QUOTE_H_INCLUDED_
00049
00050 namespace cttl_impl {
00051
00057 typedef xtl_wrap< xtl_bool< true > >
00058 relaxed_bool_T;
00059
00088 template< typename LeftT, typename MiddleT, typename RightT, typename DerivedT >
00089 class xtl_quote_base {
00090
00091 protected:
00093 LeftT m_left;
00094
00096 MiddleT m_middle;
00097
00099 RightT m_right;
00100
00101 public:
00102
00103
00105 xtl_quote_base( LeftT const& left_, MiddleT const& middle_, RightT const& right_ )
00106 : m_left( left_ ), m_middle( middle_ ), m_right( right_ )
00107 {
00108 }
00109
00110
00111
00135 template< typename SubstrT >
00136 size_t match( SubstrT& edge_ )
00137 {
00138
00139 CTTL_TRACE_LEVEL_MATCH( '\"' );
00140 typename SubstrT::offset_guard_T saved_first_offset( edge_.first );
00141 typename SubstrT::offset_guard_T left_offset( edge_.first, m_left.match( edge_ ) );
00142
00143 if ( left_offset != SubstrT::string_T::npos ) {
00144 if ( static_cast< DerivedT* >( this )->match_pair( edge_ ) )
00145 return left_offset;
00146 }
00147
00148 edge_.first.offset( saved_first_offset );
00149 CTTL_TRACE_TEXT_RESULT( false, '\"', "xtl_quote_base: opening close failed" );
00150 return SubstrT::string_T::npos;
00151 }
00152
00176 template< typename SubstrT >
00177 size_t find( SubstrT& edge_ )
00178 {
00179
00180 CTTL_TRACE_LEVEL_FIND( '\"' );
00181 typename SubstrT::offset_guard_T saved_first_offset( edge_.first );
00182 typename SubstrT::offset_guard_T left_offset( edge_.first, m_left.find( edge_ ) );
00183 if ( left_offset != SubstrT::string_T::npos ) {
00184 if ( static_cast< DerivedT* >( this )->match_pair( edge_ ) )
00185 return left_offset;
00186 }
00187
00188 edge_.first.offset( saved_first_offset );
00189 CTTL_TRACE_TEXT_RESULT( false, '\"', "xtl_quote_base: opening clause failed" );
00190 return SubstrT::string_T::npos;
00191 }
00192
00216 template< typename SubstrT >
00217 size_t bang_find( SubstrT& edge_ )
00218 {
00219
00220 CTTL_TRACE_LEVEL_BANG( '\"' );
00221 typename SubstrT::offset_guard_T saved_first_offset( edge_.first );
00222
00223 typename SubstrT::offset_guard_T iteration_offset( edge_.first, SubstrT::string_T::npos );
00224 typename SubstrT::offset_guard_T left_offset( edge_.first, SubstrT::string_T::npos );
00225
00226 while ( ( left_offset = m_left.bang_find( edge_ ) ) != SubstrT::string_T::npos ) {
00227 if ( static_cast< DerivedT* >( this )->match_pair( edge_ ) )
00228 return left_offset;
00229
00230 if ( iteration_offset == edge_.first.offset() ) {
00231 CTTL_TRACE_TEXT( '\"', "!!quote(left,middle,right): search made no progress: bailing out" );
00232 break;
00233 }
00234
00235 iteration_offset = edge_.first.offset();
00236 }
00237
00238 edge_.first.offset( saved_first_offset );
00239 CTTL_TRACE_TEXT_RESULT( false, '\"', "xtl_quote_base: LHS bang_find failed" );
00240 return SubstrT::string_T::npos;
00241 }
00242
00243 private:
00245 xtl_quote_base< LeftT, MiddleT, RightT, DerivedT >& operator=( xtl_quote_base< LeftT, MiddleT, RightT, DerivedT > const& );
00246
00247 };
00248
00249
00271 template< typename LeftT, typename MiddleT, typename RightT >
00272 class xtl_quote_generic : public xtl_quote_base< LeftT, MiddleT, RightT, xtl_quote_generic< LeftT, MiddleT, RightT > > {
00273 public:
00274
00275
00277 xtl_quote_generic( LeftT const& left_, MiddleT const& middle_, RightT const& right_ )
00278 : xtl_quote_base< LeftT, MiddleT, RightT, xtl_quote_generic< LeftT, MiddleT, RightT > >( left_, middle_, right_ )
00279 {
00280 }
00281
00282
00283
00288 template< typename SubstrT >
00289 bool match_pair( SubstrT& edge_ )
00290 {
00291
00292 typename SubstrT::offset_guard_T middle_offset_start( edge_.first );
00293 size_t level = 1;
00294
00295 typename SubstrT::offset_guard_T current_offset( edge_.first );
00296 typename SubstrT::offset_guard_T right_offset( edge_.first, SubstrT::string_T::npos );
00297 typename SubstrT::offset_guard_T right_right_offset( edge_.first, SubstrT::string_T::npos );
00298
00299 for (
00300 ;
00301 level && ( ( right_offset = this->m_right.bang_find( edge_ ) ) != SubstrT::string_T::npos );
00302 current_offset = edge_.first.offset()
00303 )
00304 {
00305
00306
00307 right_right_offset = edge_.first.offset( current_offset );
00308 size_t left_offset = this->m_left.bang_find( edge_ );
00309 if ( left_offset != SubstrT::string_T::npos )
00310 if ( left_offset < right_offset ) {
00311
00312 ++level;
00313 continue;
00314 }
00315
00316
00317 edge_.first.offset( right_right_offset );
00318 --level;
00319 }
00320
00321 if ( level ) {
00322
00323 CTTL_TRACE_TEXT_RESULT( false, '\"', "xtl_quote_generic: closing clause not found" );
00324 return false;
00325 }
00326
00327
00328 xtl_edge_offset_guard< SubstrT > edge_guard( edge_ );
00329 edge_.first.offset( middle_offset_start );
00330 edge_.second.offset( right_offset );
00331 if ( this->m_middle.match( edge_ ) != SubstrT::string_T::npos ) {
00332 edge_guard.restore( edge_ );
00333 return true;
00334 }
00335
00336 edge_guard.restore( edge_ );
00337 CTTL_TRACE_TEXT_RESULT( false, '\"', "xtl_quote_generic: middle clause failed" );
00338 return false;
00339 }
00340
00341 private:
00343 xtl_quote_generic< LeftT, MiddleT, RightT >& operator=( xtl_quote_generic< LeftT, MiddleT, RightT > const& );
00344
00345 };
00346
00347
00363 template< typename MiddleT, typename RightT >
00364 class xtl_quote_bool : public xtl_quote_base< relaxed_bool_T, MiddleT, RightT, xtl_quote_bool< MiddleT, RightT > > {
00365
00366 public:
00367
00368
00370 xtl_quote_bool( MiddleT const& middle_, RightT const& right_ )
00371 : xtl_quote_base< relaxed_bool_T, MiddleT, RightT, xtl_quote_bool< MiddleT, RightT > >( true, middle_, right_ )
00372 {
00373 }
00374
00375
00376
00382 template< typename SubstrT >
00383 bool match_pair( SubstrT& edge_ )
00384 {
00385
00386 typename SubstrT::offset_guard_T middle_offset_start( edge_.first );
00387 typename SubstrT::offset_guard_T right_offset( edge_.first, this->m_right.bang_find( edge_ ) );
00388
00389 if ( right_offset != SubstrT::string_T::npos ) {
00390
00391
00392 xtl_edge_offset_guard< SubstrT > edge_guard( edge_ );
00393 edge_.first.offset( middle_offset_start );
00394 edge_.second.offset( right_offset );
00395 if ( this->m_middle.match( edge_ ) != SubstrT::string_T::npos ) {
00396 edge_guard.restore( edge_ );
00397 return true;
00398 }
00399 edge_guard.restore( edge_ );
00400 CTTL_TRACE_TEXT_RESULT( false, '\"', "quote(true,M,R) middle clause failed" );
00401 return false;
00402 }
00403
00404 CTTL_TRACE_TEXT_RESULT( false, '\"', "quote(true,M,R) closing clause failed" );
00405 return false;
00406 }
00407
00408 };
00409
00410
00431 template< typename SubstrT, typename MiddleT, typename RightT, typename CharT >
00432 inline bool
00433 xtl_match_quote( SubstrT& edge_, MiddleT& middle_, RightT& right_, CharT const* chars2find_ )
00434 {
00435 typename SubstrT::string_T const& str = edge_.parent();
00436
00437
00438 const CharT close_quote = chars2find_[ 0 ];
00439 const CharT back_whack = CharT( '\\' );
00440 const CharT cr = CharT( '\r' );
00441 const CharT lf = CharT( '\n' );
00442
00443
00444 size_t middle_offset_start = edge_.first.offset();
00445 size_t current_offset = edge_.first.offset();
00446
00447
00448 size_t close_offset = SubstrT::string_T::npos;
00449 for (
00450 size_t temp_offset = str.find_first_of( chars2find_, current_offset );
00451 temp_offset != SubstrT::string_T::npos;
00452 temp_offset = str.find_first_of( chars2find_, temp_offset + 1 )
00453 )
00454 {
00455 if ( edge_.second.offset() <= temp_offset )
00456
00457 return false;
00458
00459
00460 size_t adjusted_offset = edge_.space_policy().lower_bound( temp_offset, edge_.second.offset() );
00461 if ( adjusted_offset != temp_offset ) {
00462 temp_offset = adjusted_offset - 1;
00463 if ( edge_.second.offset() <= temp_offset )
00464
00465 return false;
00466 continue;
00467 }
00468
00469
00470 if ( str[ temp_offset ] == back_whack ) {
00471
00472 ++temp_offset;
00473
00474
00475 if ( str[ temp_offset ] == cr )
00476 ++temp_offset;
00477
00478 else if ( str[ temp_offset ] == lf )
00479 ++temp_offset;
00480
00481 } else if ( str[ temp_offset ] == close_quote ) {
00482
00483 close_offset = temp_offset;
00484 break;
00485 }
00486
00487
00488 if ( ( str[ temp_offset ] == cr ) || ( str[ temp_offset ] == lf ) )
00489
00490 return false;
00491 }
00492
00493 if ( close_offset == SubstrT::string_T::npos )
00494
00495 return false;
00496
00497 edge_.first.offset( close_offset );
00498
00499
00500 typename SubstrT::strict_edge_T strict_universe( edge_ );
00501 size_t right_offset = right_.match( strict_universe );
00502
00503
00504
00505
00506 edge_.first = strict_universe.first.offset();
00507 edge_.second = strict_universe.second.offset();
00508
00509 if ( right_offset == SubstrT::string_T::npos ) {
00510 assert( false );
00511 return false;
00512 }
00513
00514 xtl_edge_offset_guard< SubstrT > edge_guard( edge_ );
00515 edge_.first.offset( middle_offset_start );
00516 edge_.second.offset( right_offset );
00517 if ( middle_.match( edge_ ) != SubstrT::string_T::npos ) {
00518 edge_guard.restore( edge_ );
00519 return true;
00520 }
00521 edge_guard.restore( edge_ );
00522 return false;
00523
00524 }
00525
00526
00540 template< typename MiddleT, typename CharT >
00541 class xtl_quote_ansi_double_quote : public xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_ansi_double_quote< MiddleT, CharT > > {
00542 public:
00543
00544
00546 xtl_quote_ansi_double_quote()
00547 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, relaxed_bool_T, xtl_wrap< xtl_char< CharT > >, xtl_quote_ansi_double_quote< relaxed_bool_T, CharT > >( CharT( '\"' ), true, CharT( '\"' ) )
00548 {
00549 }
00550
00552 xtl_quote_ansi_double_quote( MiddleT const& middle_ )
00553 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_ansi_double_quote< MiddleT, CharT > >( CharT( '\"' ), middle_, CharT( '\"' ) )
00554 {
00555 }
00556
00557
00558
00563 template< typename SubstrT >
00564 bool match_pair( SubstrT& edge_ )
00565 {
00566
00567 static const CharT chars2find[] = { CharT( '\"' ), CharT( '\n' ), CharT( '\r' ), 0x00 };
00568 return xtl_match_quote( edge_, this->m_middle, this->m_right, chars2find );
00569 }
00570
00571 private:
00573 xtl_quote_ansi_double_quote< MiddleT, CharT >& operator=( xtl_quote_ansi_double_quote< MiddleT, CharT > const& );
00574
00575 };
00576
00577
00590 template< typename MiddleT, typename CharT >
00591 class xtl_quote_ansi_single_quote : public xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_ansi_single_quote< MiddleT, CharT > > {
00592
00593 public:
00594
00595
00596
00598 xtl_quote_ansi_single_quote()
00599 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, relaxed_bool_T, xtl_wrap< xtl_char< CharT > >, xtl_quote_ansi_single_quote< relaxed_bool_T, CharT > >( CharT( '\'' ), true, CharT( '\'' ) )
00600 {
00601 }
00602
00604 xtl_quote_ansi_single_quote( MiddleT const& middle_ )
00605 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_ansi_single_quote< MiddleT, CharT > >( CharT( '\'' ), middle_, CharT( '\'' ) )
00606 {
00607 }
00608
00609
00610
00615 template< typename SubstrT >
00616 bool match_pair( SubstrT& edge_ )
00617 {
00618
00619 static const CharT chars2find[] = { CharT( '\'' ), CharT( '\n' ), CharT( '\r' ), 0x00 };
00620 return xtl_match_quote( edge_, this->m_middle, this->m_right, chars2find );
00621 }
00622
00623 private:
00625 xtl_quote_ansi_single_quote< MiddleT, CharT >& operator=( xtl_quote_ansi_single_quote< MiddleT, CharT > const& );
00626
00627 };
00628
00629
00643 template< typename MiddleT, typename CharT >
00644 class xtl_quote_c_double_quote : public xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_c_double_quote< MiddleT, CharT > > {
00645
00646 public:
00647
00648
00649
00651 xtl_quote_c_double_quote()
00652 : xtl_quote_base<
00653 xtl_wrap< xtl_char< CharT > >,
00654 relaxed_bool_T,
00655 xtl_wrap< xtl_char< CharT > >,
00656 xtl_quote_c_double_quote< xtl_wrap< xtl_bool< true > >, CharT >
00657 >( CharT( '\"' ), true, CharT( '\"' ) )
00658 {
00659 }
00660
00662 xtl_quote_c_double_quote( MiddleT const& middle_ )
00663 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_c_double_quote< MiddleT, CharT > >( CharT( '\"' ), middle_, CharT( '\"' ) )
00664 {
00665 }
00666
00667
00668
00673 template< typename SubstrT >
00674 bool match_pair( SubstrT& edge_ )
00675 {
00676
00677 static const CharT chars2find[] = { CharT( '\"' ), CharT( '\n' ), CharT( '\r' ), CharT( '\\' ), 0x00 };
00678 return xtl_match_quote( edge_, this->m_middle, this->m_right, chars2find );
00679 }
00680
00681 private:
00683 xtl_quote_c_double_quote< MiddleT, CharT >& operator=( xtl_quote_c_double_quote< MiddleT, CharT > const& );
00684
00685 };
00686
00687
00701 template< typename MiddleT, typename CharT >
00702 class xtl_quote_c_single_quote : public xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_c_single_quote< MiddleT, CharT > > {
00703
00704 public:
00705
00706
00707
00709 xtl_quote_c_single_quote()
00710 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, relaxed_bool_T, xtl_wrap< xtl_char< CharT > >, xtl_quote_c_single_quote< relaxed_bool_T, CharT > >( CharT( '\'' ), true, CharT( '\'' ) )
00711 {
00712 }
00713
00715 xtl_quote_c_single_quote( MiddleT const& middle_ )
00716 : xtl_quote_base< xtl_wrap< xtl_char< CharT > >, MiddleT, xtl_wrap< xtl_char< CharT > >, xtl_quote_c_single_quote< MiddleT, CharT > >( CharT( '\'' ), middle_, CharT( '\'' ) )
00717 {
00718 }
00719
00720
00721
00726 template< typename SubstrT >
00727 bool match_pair( SubstrT& edge_ )
00728 {
00729
00730 static const CharT chars2find[] = { CharT( '\'' ), CharT( '\n' ), CharT( '\r' ), CharT( '\\' ), 0x00 };
00731 return xtl_match_quote( edge_, this->m_middle, this->m_right, chars2find );
00732 }
00733
00734 private:
00736 xtl_quote_c_single_quote< MiddleT, CharT >& operator=( xtl_quote_c_single_quote< MiddleT, CharT > const& );
00737
00738 };
00739
00741 typedef xtl_wrap< xtl_quote_ansi_single_quote< relaxed_bool_T, CTTL_STD_CHAR > >
00742 ansi_single_quote_T;
00743
00745 typedef xtl_wrap< xtl_quote_ansi_double_quote< relaxed_bool_T, CTTL_STD_CHAR > >
00746 ansi_double_quote_T;
00747
00749 typedef xtl_wrap< xtl_quote_c_single_quote< relaxed_bool_T, CTTL_STD_CHAR > >
00750 c_single_quote_T;
00751
00753 typedef xtl_wrap< xtl_quote_c_double_quote< relaxed_bool_T, CTTL_STD_CHAR > >
00754 c_double_quote_T;
00755
00756
00758 typedef xtl_wrap< xtl_quote_ansi_single_quote< relaxed_bool_T, CTTL_STD_WCHAR > >
00759 wchar_ansi_single_quote_T;
00760
00762 typedef xtl_wrap< xtl_quote_ansi_double_quote< relaxed_bool_T, CTTL_STD_WCHAR > >
00763 wchar_ansi_double_quote_T;
00764
00766 typedef xtl_wrap< xtl_quote_c_single_quote< relaxed_bool_T, CTTL_STD_WCHAR > >
00767 wchar_c_single_quote_T;
00768
00770 typedef xtl_wrap< xtl_quote_c_double_quote< relaxed_bool_T, CTTL_STD_WCHAR > >
00771 wchar_c_double_quote_T;
00772
00773 }
00774
00775
00776 #endif // _CTTL_XTL_QUOTE_H_INCLUDED_