LCOV - code coverage report
Current view: top level - usr/include/boost/regex/v4 - perl_matcher_common.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 351 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 87 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright (c) 2002
       4             :  * John Maddock
       5             :  *
       6             :  * Use, modification and distribution are subject to the 
       7             :  * Boost Software License, Version 1.0. (See accompanying file 
       8             :  * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       9             :  *
      10             :  */
      11             : 
      12             :  /*
      13             :   *   LOCATION:    see http://www.boost.org for most recent version.
      14             :   *   FILE         perl_matcher_common.cpp
      15             :   *   VERSION      see <boost/version.hpp>
      16             :   *   DESCRIPTION: Definitions of perl_matcher member functions that are 
      17             :   *                common to both the recursive and non-recursive versions.
      18             :   */
      19             : 
      20             : #ifndef BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
      21             : #define BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
      22             : 
      23             : #ifdef BOOST_MSVC
      24             : #pragma warning(push)
      25             : #pragma warning(disable: 4103)
      26             : #endif
      27             : #ifdef BOOST_HAS_ABI_HEADERS
      28             : #  include BOOST_ABI_PREFIX
      29             : #endif
      30             : #ifdef BOOST_MSVC
      31             : #pragma warning(pop)
      32             : #endif
      33             : 
      34             : #ifdef __BORLANDC__
      35             : #  pragma option push -w-8008 -w-8066
      36             : #endif
      37             : #ifdef BOOST_MSVC
      38             : #  pragma warning(push)
      39             : #if BOOST_MSVC < 1910
      40             : #pragma warning(disable:4800)
      41             : #endif
      42             : #endif
      43             : 
      44             : namespace boost{
      45             : namespace BOOST_REGEX_DETAIL_NS{
      46             : 
      47             : template <class BidiIterator, class Allocator, class traits>
      48           0 : void perl_matcher<BidiIterator, Allocator, traits>::construct_init(const basic_regex<char_type, traits>& e, match_flag_type f)
      49             : { 
      50             :    typedef typename regex_iterator_traits<BidiIterator>::iterator_category category;
      51             :    typedef typename basic_regex<char_type, traits>::flag_type expression_flag_type;
      52             :    
      53           0 :    if(e.empty())
      54             :    {
      55             :       // precondition failure: e is not a valid regex.
      56           0 :       std::invalid_argument ex("Invalid regular expression object");
      57           0 :       boost::throw_exception(ex);
      58             :    }
      59           0 :    pstate = 0;
      60           0 :    m_match_flags = f;
      61           0 :    estimate_max_state_count(static_cast<category*>(0));
      62           0 :    expression_flag_type re_f = re.flags();
      63           0 :    icase = re_f & regex_constants::icase;
      64           0 :    if(!(m_match_flags & (match_perl|match_posix)))
      65             :    {
      66           0 :       if((re_f & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
      67           0 :          m_match_flags |= match_perl;
      68           0 :       else if((re_f & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
      69           0 :          m_match_flags |= match_perl;
      70           0 :       else if((re_f & (regbase::main_option_type|regbase::literal)) == (regbase::literal))
      71           0 :          m_match_flags |= match_perl;
      72             :       else
      73           0 :          m_match_flags |= match_posix;
      74             :    }
      75           0 :    if(m_match_flags & match_posix)
      76             :    {
      77           0 :       m_temp_match.reset(new match_results<BidiIterator, Allocator>());
      78           0 :       m_presult = m_temp_match.get();
      79             :    }
      80             :    else
      81           0 :       m_presult = &m_result;
      82             : #ifdef BOOST_REGEX_NON_RECURSIVE
      83           0 :    m_stack_base = 0;
      84           0 :    m_backup_state = 0;
      85             : #elif defined(BOOST_REGEX_RECURSIVE)
      86             :    m_can_backtrack = true;
      87             :    m_have_accept = false;
      88             : #endif
      89             :    // find the value to use for matching word boundaries:
      90           0 :    m_word_mask = re.get_data().m_word_mask; 
      91             :    // find bitmask to use for matching '.':
      92           0 :    match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? BOOST_REGEX_DETAIL_NS::test_not_newline : BOOST_REGEX_DETAIL_NS::test_newline);
      93             :    // Disable match_any if requested in the state machine:
      94           0 :    if(e.get_data().m_disable_match_any)
      95           0 :       m_match_flags &= regex_constants::match_not_any;
      96           0 : }
      97             : 
      98             : template <class BidiIterator, class Allocator, class traits>
      99           0 : void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
     100             : {
     101             :    //
     102             :    // How many states should we allow our machine to visit before giving up?
     103             :    // This is a heuristic: it takes the greater of O(N^2) and O(NS^2)
     104             :    // where N is the length of the string, and S is the number of states
     105             :    // in the machine.  It's tempting to up this to O(N^2S) or even O(N^2S^2)
     106             :    // but these take unreasonably amounts of time to bale out in pathological
     107             :    // cases.
     108             :    //
     109             :    // Calculate NS^2 first:
     110             :    //
     111             :    static const std::ptrdiff_t k = 100000;
     112           0 :    std::ptrdiff_t dist = boost::BOOST_REGEX_DETAIL_NS::distance(base, last);
     113           0 :    if(dist == 0)
     114           0 :       dist = 1;
     115           0 :    std::ptrdiff_t states = re.size();
     116           0 :    if(states == 0)
     117           0 :       states = 1;
     118           0 :    if ((std::numeric_limits<std::ptrdiff_t>::max)() / states < states)
     119             :    {
     120           0 :       max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
     121           0 :       return;
     122             :    }
     123           0 :    states *= states;
     124           0 :    if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
     125             :    {
     126           0 :       max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
     127           0 :       return;
     128             :    }
     129           0 :    states *= dist;
     130           0 :    if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
     131             :    {
     132           0 :       max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
     133           0 :       return;
     134             :    }
     135           0 :    states += k;
     136             : 
     137           0 :    max_state_count = states;
     138             : 
     139             :    //
     140             :    // Now calculate N^2:
     141             :    //
     142           0 :    states = dist;
     143           0 :    if((std::numeric_limits<std::ptrdiff_t>::max)() / dist < states)
     144             :    {
     145           0 :       max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
     146           0 :       return;
     147             :    }
     148           0 :    states *= dist;
     149           0 :    if((std::numeric_limits<std::ptrdiff_t>::max)() - k < states)
     150             :    {
     151           0 :       max_state_count = (std::min)((std::ptrdiff_t)BOOST_REGEX_MAX_STATE_COUNT, (std::numeric_limits<std::ptrdiff_t>::max)() - 2);
     152           0 :       return;
     153             :    }
     154           0 :    states += k;
     155             :    //
     156             :    // N^2 can be a very large number indeed, to prevent things getting out
     157             :    // of control, cap the max states:
     158             :    //
     159             :    if(states > BOOST_REGEX_MAX_STATE_COUNT)
     160             :       states = BOOST_REGEX_MAX_STATE_COUNT;
     161             :    //
     162             :    // If (the possibly capped) N^2 is larger than our first estimate,
     163             :    // use this instead:
     164             :    //
     165           0 :    if(states > max_state_count)
     166           0 :       max_state_count = states;
     167             : }
     168             : 
     169             : template <class BidiIterator, class Allocator, class traits>
     170             : inline void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
     171             : {
     172             :    // we don't know how long the sequence is:
     173             :    max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
     174             : }
     175             : 
     176             : #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
     177             : template <class BidiIterator, class Allocator, class traits>
     178             : inline bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
     179             :    protected_proc_type proc)
     180             : {
     181             :    ::boost::BOOST_REGEX_DETAIL_NS::concrete_protected_call
     182             :       <perl_matcher<BidiIterator, Allocator, traits> >
     183             :       obj(this, proc);
     184             :    return obj.execute();
     185             : 
     186             : }
     187             : #endif
     188             : 
     189             : template <class BidiIterator, class Allocator, class traits>
     190           0 : inline bool perl_matcher<BidiIterator, Allocator, traits>::match()
     191             : {
     192             : #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
     193             :    return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::match_imp);
     194             : #else
     195           0 :    return match_imp();
     196             : #endif
     197             : }
     198             : 
     199             : template <class BidiIterator, class Allocator, class traits>
     200           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
     201             : {
     202             :    // initialise our stack if we are non-recursive:
     203             : #ifdef BOOST_REGEX_NON_RECURSIVE
     204           0 :    save_state_init init(&m_stack_base, &m_backup_state);
     205           0 :    used_block_count = BOOST_REGEX_MAX_BLOCKS;
     206             : #if !defined(BOOST_NO_EXCEPTIONS)
     207             :    try{
     208             : #endif
     209             : #endif
     210             : 
     211             :    // reset our state machine:
     212           0 :    position = base;
     213           0 :    search_base = base;
     214           0 :    state_count = 0;
     215           0 :    m_match_flags |= regex_constants::match_all;
     216           0 :    m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);
     217           0 :    m_presult->set_base(base);
     218           0 :    m_presult->set_named_subs(this->re.get_named_subs());
     219           0 :    if(m_match_flags & match_posix)
     220           0 :       m_result = *m_presult;
     221           0 :    verify_options(re.flags(), m_match_flags);
     222           0 :    if(0 == match_prefix())
     223             :       return false;
     224           0 :    return (m_result[0].second == last) && (m_result[0].first == base);
     225             : 
     226             : #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
     227             :    }
     228           0 :    catch(...)
     229             :    {
     230             :       // unwind all pushed states, apart from anything else this
     231             :       // ensures that all the states are correctly destructed
     232             :       // not just the memory freed.
     233           0 :       while(unwind(true)){}
     234           0 :       throw;
     235             :    }
     236             : #endif
     237             : }
     238             : 
     239             : template <class BidiIterator, class Allocator, class traits>
     240           0 : inline bool perl_matcher<BidiIterator, Allocator, traits>::find()
     241             : {
     242             : #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
     243             :    return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::find_imp);
     244             : #else
     245           0 :    return find_imp();
     246             : #endif
     247             : }
     248             : 
     249             : template <class BidiIterator, class Allocator, class traits>
     250           0 : bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
     251             : {
     252             :    static matcher_proc_type const s_find_vtable[7] = 
     253             :    {
     254             :       &perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
     255             :       &perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
     256             :       &perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
     257             :       &perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
     258             :       &perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
     259             :       &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
     260             :       &perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
     261             :    };
     262             : 
     263             :    // initialise our stack if we are non-recursive:
     264             : #ifdef BOOST_REGEX_NON_RECURSIVE
     265           0 :    save_state_init init(&m_stack_base, &m_backup_state);
     266           0 :    used_block_count = BOOST_REGEX_MAX_BLOCKS;
     267             : #if !defined(BOOST_NO_EXCEPTIONS)
     268             :    try{
     269             : #endif
     270             : #endif
     271             : 
     272           0 :    state_count = 0;
     273           0 :    if((m_match_flags & regex_constants::match_init) == 0)
     274             :    {
     275             :       // reset our state machine:
     276           0 :       search_base = position = base;
     277           0 :       pstate = re.get_first_state();
     278           0 :       m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);
     279           0 :       m_presult->set_base(base);
     280           0 :       m_presult->set_named_subs(this->re.get_named_subs());
     281           0 :       m_match_flags |= regex_constants::match_init;
     282             :    }
     283             :    else
     284             :    {
     285             :       // start again:
     286           0 :       search_base = position = m_result[0].second;
     287             :       // If last match was null and match_not_null was not set then increment
     288             :       // our start position, otherwise we go into an infinite loop:
     289           0 :       if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))
     290             :       {
     291           0 :          if(position == last)
     292             :             return false;
     293             :          else 
     294           0 :             ++position;
     295             :       }
     296             :       // reset $` start:
     297           0 :       m_presult->set_size((m_match_flags & match_nosubs) ? 1u : static_cast<typename results_type::size_type>(1u + re.mark_count()), search_base, last);
     298             :       //if((base != search_base) && (base == backstop))
     299             :       //   m_match_flags |= match_prev_avail;
     300             :    }
     301           0 :    if(m_match_flags & match_posix)
     302             :    {
     303           0 :       m_result.set_size(static_cast<typename results_type::size_type>(1u + re.mark_count()), base, last);
     304           0 :       m_result.set_base(base);
     305             :    }
     306             : 
     307           0 :    verify_options(re.flags(), m_match_flags);
     308             :    // find out what kind of expression we have:
     309           0 :    unsigned type = (m_match_flags & match_continuous) ? 
     310             :       static_cast<unsigned int>(regbase::restart_continue) 
     311           0 :          : static_cast<unsigned int>(re.get_restart_type());
     312             : 
     313             :    // call the appropriate search routine:
     314           0 :    matcher_proc_type proc = s_find_vtable[type];
     315           0 :    return (this->*proc)();
     316             : 
     317             : #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
     318             :    }
     319           0 :    catch(...)
     320             :    {
     321             :       // unwind all pushed states, apart from anything else this
     322             :       // ensures that all the states are correctly destructed
     323             :       // not just the memory freed.
     324           0 :       while(unwind(true)){}
     325           0 :       throw;
     326             :    }
     327             : #endif
     328             : }
     329             : 
     330             : template <class BidiIterator, class Allocator, class traits>
     331           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()
     332             : {
     333           0 :    m_has_partial_match = false;
     334           0 :    m_has_found_match = false;
     335           0 :    pstate = re.get_first_state();
     336           0 :    m_presult->set_first(position);
     337           0 :    restart = position;
     338           0 :    match_all_states();
     339           0 :    if(!m_has_found_match && m_has_partial_match && (m_match_flags & match_partial))
     340             :    {
     341           0 :       m_has_found_match = true;
     342           0 :       m_presult->set_second(last, 0, false);
     343           0 :       position = last;
     344           0 :       if((m_match_flags & match_posix) == match_posix)
     345             :       {
     346           0 :          m_result.maybe_assign(*m_presult);
     347             :       }
     348             :    }
     349             : #ifdef BOOST_REGEX_MATCH_EXTRA
     350             :    if(m_has_found_match && (match_extra & m_match_flags))
     351             :    {
     352             :       //
     353             :       // we have a match, reverse the capture information:
     354             :       //
     355             :       for(unsigned i = 0; i < m_presult->size(); ++i)
     356             :       {
     357             :          typename sub_match<BidiIterator>::capture_sequence_type & seq = ((*m_presult)[i]).get_captures();
     358             :          std::reverse(seq.begin(), seq.end());
     359             :       }
     360             :    }
     361             : #endif
     362           0 :    if(!m_has_found_match)
     363           0 :       position = restart; // reset search postion
     364             : #ifdef BOOST_REGEX_RECURSIVE
     365             :    m_can_backtrack = true; // reset for further searches
     366             : #endif
     367           0 :    return m_has_found_match;
     368             : }
     369             : 
     370             : template <class BidiIterator, class Allocator, class traits>
     371           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
     372             : {
     373           0 :    unsigned int len = static_cast<const re_literal*>(pstate)->length;
     374           0 :    const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
     375             :    //
     376             :    // compare string with what we stored in
     377             :    // our records:
     378           0 :    for(unsigned int i = 0; i < len; ++i, ++position)
     379             :    {
     380           0 :       if((position == last) || (traits_inst.translate(*position, icase) != what[i]))
     381           0 :          return false;
     382             :    }
     383           0 :    pstate = pstate->next.p;
     384           0 :    return true;
     385             : }
     386             : 
     387             : template <class BidiIterator, class Allocator, class traits>
     388           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
     389             : {
     390           0 :    if(position == backstop)
     391             :    {
     392           0 :       if((m_match_flags & match_prev_avail) == 0)
     393             :       {
     394           0 :          if((m_match_flags & match_not_bol) == 0)
     395             :          {
     396           0 :             pstate = pstate->next.p;
     397           0 :             return true;
     398             :          }
     399             :          return false;
     400             :       }
     401             :    }
     402           0 :    else if(m_match_flags & match_single_line)
     403             :       return false;
     404             : 
     405             :    // check the previous value character:
     406           0 :    BidiIterator t(position);
     407           0 :    --t;
     408           0 :    if(position != last)
     409             :    {
     410           0 :       if(is_separator(*t) && !((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n'))) )
     411             :       {
     412           0 :          pstate = pstate->next.p;
     413           0 :          return true;
     414             :       }
     415             :    }
     416           0 :    else if(is_separator(*t))
     417             :    {
     418           0 :       pstate = pstate->next.p;
     419           0 :       return true;
     420             :    }
     421             :    return false;
     422             : }
     423             : 
     424             : template <class BidiIterator, class Allocator, class traits>
     425           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
     426             : {
     427           0 :    if(position != last)
     428             :    {
     429           0 :       if(m_match_flags & match_single_line)
     430             :          return false;
     431             :       // we're not yet at the end so *first is always valid:
     432           0 :       if(is_separator(*position))
     433             :       {
     434           0 :          if((position != backstop) || (m_match_flags & match_prev_avail))
     435             :          {
     436             :             // check that we're not in the middle of \r\n sequence
     437           0 :             BidiIterator t(position);
     438           0 :             --t;
     439           0 :             if((*t == static_cast<char_type>('\r')) && (*position == static_cast<char_type>('\n')))
     440             :             {
     441           0 :                return false;
     442             :             }
     443             :          }
     444           0 :          pstate = pstate->next.p;
     445           0 :          return true;
     446             :       }
     447             :    }
     448           0 :    else if((m_match_flags & match_not_eol) == 0)
     449             :    {
     450           0 :       pstate = pstate->next.p;
     451           0 :       return true;
     452             :    }
     453             :    return false;
     454             : }
     455             : 
     456             : template <class BidiIterator, class Allocator, class traits>
     457           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
     458             : {
     459           0 :    if(position == last) 
     460             :       return false;
     461           0 :    if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))
     462             :       return false;
     463           0 :    if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
     464             :       return false;
     465           0 :    pstate = pstate->next.p;
     466           0 :    ++position;
     467           0 :    return true;
     468             : }
     469             : 
     470             : template <class BidiIterator, class Allocator, class traits>
     471           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
     472             : {
     473             :    bool b; // indcates whether next character is a word character
     474           0 :    if(position != last)
     475             :    {
     476             :       // prev and this character must be opposites:
     477           0 :       b = traits_inst.isctype(*position, m_word_mask);
     478             :    }
     479             :    else
     480             :    {
     481           0 :       if (m_match_flags & match_not_eow)
     482             :          return false;
     483             :       b = false;
     484             :    }
     485           0 :    if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
     486             :    {
     487           0 :       if(m_match_flags & match_not_bow)
     488             :          return false;
     489             :       else
     490           0 :          b ^= false;
     491             :    }
     492             :    else
     493             :    {
     494           0 :       --position;
     495           0 :       b ^= traits_inst.isctype(*position, m_word_mask);
     496           0 :       ++position;
     497             :    }
     498           0 :    if(b)
     499             :    {
     500           0 :       pstate = pstate->next.p;
     501           0 :       return true;
     502             :    }
     503             :    return false; // no match if we get to here...
     504             : }
     505             : 
     506             : template <class BidiIterator, class Allocator, class traits>
     507           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
     508             : {
     509           0 :    if(position == last)
     510             :       return false;
     511             :    // both prev and this character must be m_word_mask:
     512           0 :    bool prev = traits_inst.isctype(*position, m_word_mask);
     513             :    {
     514             :       bool b;
     515           0 :       if((position == backstop) && ((m_match_flags & match_prev_avail) == 0)) 
     516             :          return false;
     517             :       else
     518             :       {
     519           0 :          --position;
     520           0 :          b = traits_inst.isctype(*position, m_word_mask);
     521           0 :          ++position;
     522             :       }
     523           0 :       if(b == prev)
     524             :       {
     525           0 :          pstate = pstate->next.p;
     526           0 :          return true;
     527             :       }
     528             :    }
     529             :    return false;
     530             : }
     531             : 
     532             : template <class BidiIterator, class Allocator, class traits>
     533           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
     534             : {
     535           0 :    if(position == last)
     536             :       return false; // can't be starting a word if we're already at the end of input
     537           0 :    if(!traits_inst.isctype(*position, m_word_mask))
     538             :       return false; // next character isn't a word character
     539           0 :    if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
     540             :    {
     541           0 :       if(m_match_flags & match_not_bow)
     542             :          return false; // no previous input
     543             :    }
     544             :    else
     545             :    {
     546             :       // otherwise inside buffer:
     547           0 :       BidiIterator t(position);
     548           0 :       --t;
     549           0 :       if(traits_inst.isctype(*t, m_word_mask))
     550           0 :          return false; // previous character not non-word
     551             :    }
     552             :    // OK we have a match:
     553           0 :    pstate = pstate->next.p;
     554           0 :    return true;
     555             : }
     556             : 
     557             : template <class BidiIterator, class Allocator, class traits>
     558           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
     559             : {
     560           0 :    if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
     561             :       return false;  // start of buffer can't be end of word
     562           0 :    BidiIterator t(position);
     563           0 :    --t;
     564           0 :    if(traits_inst.isctype(*t, m_word_mask) == false)
     565             :       return false;  // previous character wasn't a word character
     566             : 
     567           0 :    if(position == last)
     568             :    {
     569           0 :       if(m_match_flags & match_not_eow)
     570             :          return false; // end of buffer but not end of word
     571             :    }
     572             :    else
     573             :    {
     574             :       // otherwise inside buffer:
     575           0 :       if(traits_inst.isctype(*position, m_word_mask))
     576             :          return false; // next character is a word character
     577             :    }
     578           0 :    pstate = pstate->next.p;
     579           0 :    return true;      // if we fall through to here then we've succeeded
     580             : }
     581             : 
     582             : template <class BidiIterator, class Allocator, class traits>
     583           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
     584             : {
     585           0 :    if((position != backstop) || (m_match_flags & match_not_bob))
     586             :       return false;
     587             :    // OK match:
     588           0 :    pstate = pstate->next.p;
     589           0 :    return true;
     590             : }
     591             : 
     592             : template <class BidiIterator, class Allocator, class traits>
     593           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()
     594             : {
     595           0 :    if((position != last) || (m_match_flags & match_not_eob))
     596             :       return false;
     597             :    // OK match:
     598           0 :    pstate = pstate->next.p;
     599           0 :    return true;
     600             : }
     601             : 
     602             : template <class BidiIterator, class Allocator, class traits>
     603           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_backref()
     604             : {
     605             :    //
     606             :    // Compare with what we previously matched.
     607             :    // Note that this succeeds if the backref did not partisipate
     608             :    // in the match, this is in line with ECMAScript, but not Perl
     609             :    // or PCRE.
     610             :    //
     611           0 :    int index = static_cast<const re_brace*>(pstate)->index;
     612           0 :    if(index >= 10000)
     613             :    {
     614           0 :       named_subexpressions::range_type r = re.get_data().equal_range(index);
     615           0 :       BOOST_ASSERT(r.first != r.second);
     616             :       do
     617             :       {
     618           0 :          index = r.first->index;
     619           0 :          ++r.first;
     620           0 :       }while((r.first != r.second) && ((*m_presult)[index].matched != true));
     621             :    }
     622             : 
     623           0 :    if((m_match_flags & match_perl) && !(*m_presult)[index].matched)
     624             :       return false;
     625             : 
     626           0 :    BidiIterator i = (*m_presult)[index].first;
     627           0 :    BidiIterator j = (*m_presult)[index].second;
     628           0 :    while(i != j)
     629             :    {
     630           0 :       if((position == last) || (traits_inst.translate(*position, icase) != traits_inst.translate(*i, icase)))
     631           0 :          return false;
     632           0 :       ++i;
     633           0 :       ++position;
     634             :    }
     635           0 :    pstate = pstate->next.p;
     636           0 :    return true;
     637             : }
     638             : 
     639             : template <class BidiIterator, class Allocator, class traits>
     640           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
     641             : {
     642             :    typedef typename traits::char_class_type char_class_type;
     643             :    // let the traits class do the work:
     644           0 :    if(position == last)
     645             :       return false;
     646           0 :    BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);
     647           0 :    if(t != position)
     648             :    {
     649           0 :       pstate = pstate->next.p;
     650           0 :       position = t;
     651           0 :       return true;
     652             :    }
     653             :    return false;
     654             : }
     655             : 
     656             : template <class BidiIterator, class Allocator, class traits>
     657           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_set()
     658             : {
     659           0 :    if(position == last)
     660             :       return false;
     661           0 :    if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
     662             :    {
     663           0 :       pstate = pstate->next.p;
     664           0 :       ++position;
     665           0 :       return true;
     666             :    }
     667             :    return false;
     668             : }
     669             : 
     670             : template <class BidiIterator, class Allocator, class traits>
     671           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_jump()
     672             : {
     673           0 :    pstate = static_cast<const re_jump*>(pstate)->alt.p;
     674           0 :    return true;
     675             : }
     676             : 
     677             : template <class BidiIterator, class Allocator, class traits>
     678           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_combining()
     679             : {
     680           0 :    if(position == last)
     681             :       return false;
     682           0 :    if(is_combining(traits_inst.translate(*position, icase)))
     683             :       return false;
     684           0 :    ++position;
     685           0 :    while((position != last) && is_combining(traits_inst.translate(*position, icase)))
     686           0 :       ++position;
     687           0 :    pstate = pstate->next.p;
     688           0 :    return true;
     689             : }
     690             : 
     691             : template <class BidiIterator, class Allocator, class traits>
     692           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()
     693             : {
     694           0 :    if(m_match_flags & match_not_eob)
     695             :       return false;
     696           0 :    BidiIterator p(position);
     697           0 :    while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;
     698           0 :    if(p != last)
     699             :       return false;
     700           0 :    pstate = pstate->next.p;
     701           0 :    return true;
     702             : }
     703             : 
     704             : template <class BidiIterator, class Allocator, class traits>
     705           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
     706             : {
     707           0 :    if(position == search_base)
     708             :    {
     709           0 :       pstate = pstate->next.p;
     710           0 :       return true;
     711             :    }
     712             :    return false;
     713             : }
     714             : 
     715             : template <class BidiIterator, class Allocator, class traits>
     716           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
     717             : {
     718             : #ifdef BOOST_MSVC
     719             : #pragma warning(push)
     720             : #pragma warning(disable:4127)
     721             : #endif
     722             :    if( ::boost::is_random_access_iterator<BidiIterator>::value)
     723             :    {
     724           0 :       std::ptrdiff_t maxlen = ::boost::BOOST_REGEX_DETAIL_NS::distance(backstop, position);
     725           0 :       if(maxlen < static_cast<const re_brace*>(pstate)->index)
     726             :          return false;
     727           0 :       std::advance(position, -static_cast<const re_brace*>(pstate)->index);
     728             :    }
     729             :    else
     730             :    {
     731             :       int c = static_cast<const re_brace*>(pstate)->index;
     732             :       while(c--)
     733             :       {
     734             :          if(position == backstop)
     735             :             return false;
     736             :          --position;
     737             :       }
     738             :    }
     739           0 :    pstate = pstate->next.p;
     740           0 :    return true;
     741             : #ifdef BOOST_MSVC
     742             : #pragma warning(pop)
     743             : #endif
     744             : }
     745             : 
     746             : template <class BidiIterator, class Allocator, class traits>
     747           0 : inline bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()
     748             : {
     749             :    // return true if marked sub-expression N has been matched:
     750           0 :    int index = static_cast<const re_brace*>(pstate)->index;
     751           0 :    bool result = false;
     752           0 :    if(index == 9999)
     753             :    {
     754             :       // Magic value for a (DEFINE) block:
     755             :       return false;
     756             :    }
     757           0 :    else if(index > 0)
     758             :    {
     759             :       // Have we matched subexpression "index"?
     760             :       // Check if index is a hash value:
     761           0 :       if(index >= 10000)
     762             :       {
     763           0 :          named_subexpressions::range_type r = re.get_data().equal_range(index);
     764           0 :          while(r.first != r.second)
     765             :          {
     766           0 :             if((*m_presult)[r.first->index].matched)
     767             :             {
     768             :                result = true;
     769             :                break;
     770             :             }
     771           0 :             ++r.first;
     772             :          }
     773             :       }
     774             :       else
     775             :       {
     776           0 :          result = (*m_presult)[index].matched;
     777             :       }
     778           0 :       pstate = pstate->next.p;
     779             :    }
     780             :    else
     781             :    {
     782             :       // Have we recursed into subexpression "index"?
     783             :       // If index == 0 then check for any recursion at all, otherwise for recursion to -index-1.
     784           0 :       int idx = -(index+1);
     785           0 :       if(idx >= 10000)
     786             :       {
     787           0 :          named_subexpressions::range_type r = re.get_data().equal_range(idx);
     788           0 :          int stack_index = recursion_stack.empty() ? -1 : recursion_stack.back().idx;
     789           0 :          while(r.first != r.second)
     790             :          {
     791           0 :             result |= (stack_index == r.first->index);
     792           0 :             if(result)break;
     793           0 :             ++r.first;
     794             :          }
     795             :       }
     796             :       else
     797             :       {
     798           0 :          result = !recursion_stack.empty() && ((recursion_stack.back().idx == idx) || (index == 0));
     799             :       }
     800           0 :       pstate = pstate->next.p;
     801             :    }
     802             :    return result;
     803             : }
     804             : 
     805             : template <class BidiIterator, class Allocator, class traits>
     806           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_fail()
     807             : {
     808             :    // Just force a backtrack:
     809           0 :    return false;
     810             : }
     811             : 
     812             : template <class BidiIterator, class Allocator, class traits>
     813           0 : bool perl_matcher<BidiIterator, Allocator, traits>::match_accept()
     814             : {
     815           0 :    if(!recursion_stack.empty())
     816             :    {
     817           0 :       return skip_until_paren(recursion_stack.back().idx);
     818             :    }
     819             :    else
     820             :    {
     821           0 :       return skip_until_paren(INT_MAX);
     822             :    }
     823             : }
     824             : 
     825             : template <class BidiIterator, class Allocator, class traits>
     826           0 : bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
     827             : {
     828             : #ifdef BOOST_MSVC
     829             : #pragma warning(push)
     830             : #pragma warning(disable:4127)
     831             : #endif
     832           0 :    const unsigned char* _map = re.get_map();
     833           0 :    while(true)
     834             :    {
     835             :       // skip everything we can't match:
     836           0 :       while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )
     837           0 :          ++position;
     838           0 :       if(position == last)
     839             :       {
     840             :          // run out of characters, try a null match if possible:
     841           0 :          if(re.can_be_null())
     842           0 :             return match_prefix();
     843             :          break;
     844             :       }
     845             :       // now try and obtain a match:
     846           0 :       if(match_prefix())
     847             :          return true;
     848           0 :       if(position == last)
     849             :          return false;
     850           0 :       ++position;
     851             :    }
     852             :    return false;
     853             : #ifdef BOOST_MSVC
     854             : #pragma warning(pop)
     855             : #endif
     856             : }
     857             : 
     858             : template <class BidiIterator, class Allocator, class traits>
     859           0 : bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
     860             : {
     861             : #ifdef BOOST_MSVC
     862             : #pragma warning(push)
     863             : #pragma warning(disable:4127)
     864             : #endif
     865             :    // do search optimised for word starts:
     866           0 :    const unsigned char* _map = re.get_map();
     867           0 :    if((m_match_flags & match_prev_avail) || (position != base))
     868           0 :       --position;
     869           0 :    else if(match_prefix())
     870             :       return true;
     871             :    do
     872             :    {
     873           0 :       while((position != last) && traits_inst.isctype(*position, m_word_mask))
     874           0 :          ++position;
     875           0 :       while((position != last) && !traits_inst.isctype(*position, m_word_mask))
     876           0 :          ++position;
     877           0 :       if(position == last)
     878             :          break;
     879             : 
     880           0 :       if(can_start(*position, _map, (unsigned char)mask_any) )
     881             :       {
     882           0 :          if(match_prefix())
     883             :             return true;
     884             :       }
     885           0 :       if(position == last)
     886             :          break;
     887             :    } while(true);
     888             :    return false;
     889             : #ifdef BOOST_MSVC
     890             : #pragma warning(pop)
     891             : #endif
     892             : }
     893             : 
     894             : template <class BidiIterator, class Allocator, class traits>
     895           0 : bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()
     896             : {
     897             :    // do search optimised for line starts:
     898           0 :    const unsigned char* _map = re.get_map();
     899           0 :    if(match_prefix())
     900             :       return true;
     901           0 :    while(position != last)
     902             :    {
     903           0 :       while((position != last) && !is_separator(*position))
     904           0 :          ++position;
     905           0 :       if(position == last)
     906             :          return false;
     907           0 :       ++position;
     908           0 :       if(position == last)
     909             :       {
     910           0 :          if(re.can_be_null() && match_prefix())
     911             :             return true;
     912           0 :          return false;
     913             :       }
     914             : 
     915           0 :       if( can_start(*position, _map, (unsigned char)mask_any) )
     916             :       {
     917           0 :          if(match_prefix())
     918             :             return true;
     919             :       }
     920           0 :       if(position == last)
     921             :          return false;
     922             :       //++position;
     923             :    }
     924             :    return false;
     925             : }
     926             : 
     927             : template <class BidiIterator, class Allocator, class traits>
     928           0 : bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()
     929             : {
     930           0 :    if((position == base) && ((m_match_flags & match_not_bob) == 0))
     931           0 :       return match_prefix();
     932             :    return false;
     933             : }
     934             : 
     935             : template <class BidiIterator, class Allocator, class traits>
     936           0 : bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()
     937             : {
     938             : #if 0
     939             :    if(position == last)
     940             :       return false; // can't possibly match if we're at the end already
     941             : 
     942             :    unsigned type = (m_match_flags & match_continuous) ? 
     943             :       static_cast<unsigned int>(regbase::restart_continue) 
     944             :          : static_cast<unsigned int>(re.get_restart_type());
     945             : 
     946             :    const kmp_info<char_type>* info = access::get_kmp(re);
     947             :    int len = info->len;
     948             :    const char_type* x = info->pstr;
     949             :    int j = 0; 
     950             :    while (position != last) 
     951             :    {
     952             :       while((j > -1) && (x[j] != traits_inst.translate(*position, icase))) 
     953             :          j = info->kmp_next[j];
     954             :       ++position;
     955             :       ++j;
     956             :       if(j >= len) 
     957             :       {
     958             :          if(type == regbase::restart_fixed_lit)
     959             :          {
     960             :             std::advance(position, -j);
     961             :             restart = position;
     962             :             std::advance(restart, len);
     963             :             m_result.set_first(position);
     964             :             m_result.set_second(restart);
     965             :             position = restart;
     966             :             return true;
     967             :          }
     968             :          else
     969             :          {
     970             :             restart = position;
     971             :             std::advance(position, -j);
     972             :             if(match_prefix())
     973             :                return true;
     974             :             else
     975             :             {
     976             :                for(int k = 0; (restart != position) && (k < j); ++k, --restart)
     977             :                      {} // dwa 10/20/2000 - warning suppression for MWCW
     978             :                if(restart != last)
     979             :                   ++restart;
     980             :                position = restart;
     981             :                j = 0;  //we could do better than this...
     982             :             }
     983             :          }
     984             :       }
     985             :    }
     986             :    if((m_match_flags & match_partial) && (position == last) && j)
     987             :    {
     988             :       // we need to check for a partial match:
     989             :       restart = position;
     990             :       std::advance(position, -j);
     991             :       return match_prefix();
     992             :    }
     993             : #endif
     994           0 :    return false;
     995             : }
     996             : 
     997             : } // namespace BOOST_REGEX_DETAIL_NS
     998             : 
     999             : } // namespace boost
    1000             : 
    1001             : #ifdef BOOST_MSVC
    1002             : #  pragma warning(pop)
    1003             : #endif
    1004             : 
    1005             : #ifdef __BORLANDC__
    1006             : #  pragma option pop
    1007             : #endif
    1008             : #ifdef BOOST_MSVC
    1009             : #pragma warning(push)
    1010             : #pragma warning(disable: 4103)
    1011             : #endif
    1012             : #ifdef BOOST_HAS_ABI_HEADERS
    1013             : #  include BOOST_ABI_SUFFIX
    1014             : #endif
    1015             : #ifdef BOOST_MSVC
    1016             : #pragma warning(pop)
    1017             : #endif
    1018             : 
    1019             : #endif
    1020             : 

Generated by: LCOV version 1.14