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

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright (c) 1998-2009 John Maddock
       4             :  * Copyright 2008 Eric Niebler. 
       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         regex_format.hpp
      15             :   *   VERSION      see <boost/version.hpp>
      16             :   *   DESCRIPTION: Provides formatting output routines for search and replace
      17             :   *                operations.  Note this is an internal header file included
      18             :   *                by regex.hpp, do not include on its own.
      19             :   */
      20             : 
      21             : #ifndef BOOST_REGEX_FORMAT_HPP
      22             : #define BOOST_REGEX_FORMAT_HPP
      23             : 
      24             : #include <boost/type_traits/is_pointer.hpp>
      25             : #include <boost/type_traits/is_function.hpp>
      26             : #include <boost/type_traits/is_class.hpp>
      27             : #include <boost/type_traits/is_same.hpp>
      28             : #include <boost/type_traits/is_convertible.hpp>
      29             : #include <boost/type_traits/remove_pointer.hpp>
      30             : #include <boost/type_traits/remove_cv.hpp>
      31             : #include <boost/mpl/if.hpp>
      32             : #include <boost/mpl/and.hpp>
      33             : #include <boost/mpl/not.hpp>
      34             : #ifndef BOOST_NO_SFINAE
      35             : #include <boost/mpl/has_xxx.hpp>
      36             : #endif
      37             : #include <boost/ref.hpp>
      38             : 
      39             : namespace boost{
      40             : 
      41             : #ifdef BOOST_MSVC
      42             : #pragma warning(push)
      43             : #pragma warning(disable: 4103)
      44             : #endif
      45             : #ifdef BOOST_HAS_ABI_HEADERS
      46             : #  include BOOST_ABI_PREFIX
      47             : #endif
      48             : #ifdef BOOST_MSVC
      49             : #pragma warning(pop)
      50             : #endif
      51             : 
      52             : //
      53             : // Forward declaration:
      54             : //
      55             :    template <class BidiIterator, class Allocator = BOOST_DEDUCED_TYPENAME std::vector<sub_match<BidiIterator> >::allocator_type >
      56             : class match_results;
      57             : 
      58             : namespace BOOST_REGEX_DETAIL_NS{
      59             : 
      60             : //
      61             : // struct trivial_format_traits:
      62             : // defines minimum localisation support for formatting
      63             : // in the case that the actual regex traits is unavailable.
      64             : //
      65             : template <class charT>
      66             : struct trivial_format_traits
      67             : {
      68             :    typedef charT char_type;
      69             : 
      70             :    static std::ptrdiff_t length(const charT* p)
      71             :    {
      72             :       return global_length(p);
      73             :    }
      74             :    static charT tolower(charT c)
      75             :    {
      76             :       return ::boost::BOOST_REGEX_DETAIL_NS::global_lower(c);
      77             :    }
      78             :    static charT toupper(charT c)
      79             :    {
      80             :       return ::boost::BOOST_REGEX_DETAIL_NS::global_upper(c);
      81             :    }
      82             :    static int value(const charT c, int radix)
      83             :    {
      84             :       int result = global_value(c);
      85             :       return result >= radix ? -1 : result;
      86             :    }
      87             :    int toi(const charT*& p1, const charT* p2, int radix)const
      88             :    {
      89             :       return (int)global_toi(p1, p2, radix, *this);
      90             :    }
      91             : };
      92             : 
      93             : template <class OutputIterator, class Results, class traits, class ForwardIter>
      94             : class basic_regex_formatter
      95             : {
      96             : public:
      97             :    typedef typename traits::char_type char_type;
      98           0 :    basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
      99           0 :       : m_traits(t), m_results(r), m_out(o), m_position(), m_end(), m_flags(), m_state(output_copy), m_restore_state(output_copy), m_have_conditional(false) {}
     100             :    OutputIterator format(ForwardIter p1, ForwardIter p2, match_flag_type f);
     101             :    OutputIterator format(ForwardIter p1, match_flag_type f)
     102             :    {
     103             :       return format(p1, p1 + m_traits.length(p1), f);
     104             :    }
     105             : private:
     106             :    typedef typename Results::value_type sub_match_type;
     107             :    enum output_state
     108             :    {
     109             :       output_copy,
     110             :       output_next_lower,
     111             :       output_next_upper,
     112             :       output_lower,
     113             :       output_upper,
     114             :       output_none
     115             :    };
     116             : 
     117             :    void put(char_type c);
     118             :    void put(const sub_match_type& sub);
     119             :    void format_all();
     120             :    void format_perl();
     121             :    void format_escape();
     122             :    void format_conditional();
     123             :    void format_until_scope_end();
     124             :    bool handle_perl_verb(bool have_brace);
     125             : 
     126             :    inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::false_&)
     127             :    {
     128             :       std::vector<char_type> v(i, j);
     129             :       return (i != j) ? this->m_results.named_subexpression(&v[0], &v[0] + v.size())
     130             :          : this->m_results.named_subexpression(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
     131             :    }
     132           0 :    inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j, const mpl::true_&)
     133             :    {
     134           0 :       return this->m_results.named_subexpression(i, j);
     135             :    }
     136           0 :    inline typename Results::value_type const& get_named_sub(ForwardIter i, ForwardIter j)
     137             :    {
     138             :       typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type;
     139           0 :       return get_named_sub(i, j, tag_type());
     140             :    }
     141             :    inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::false_&)
     142             :    {
     143             :       std::vector<char_type> v(i, j);
     144             :       return (i != j) ? this->m_results.named_subexpression_index(&v[0], &v[0] + v.size())
     145             :          : this->m_results.named_subexpression_index(static_cast<const char_type*>(0), static_cast<const char_type*>(0));
     146             :    }
     147           0 :    inline int get_named_sub_index(ForwardIter i, ForwardIter j, const mpl::true_&)
     148             :    {
     149           0 :       return this->m_results.named_subexpression_index(i, j);
     150             :    }
     151           0 :    inline int get_named_sub_index(ForwardIter i, ForwardIter j)
     152             :    {
     153             :       typedef typename boost::is_convertible<ForwardIter, const char_type*>::type tag_type;
     154           0 :       return get_named_sub_index(i, j, tag_type());
     155             :    }
     156             : #ifdef BOOST_MSVC
     157             :    // msvc-8.0 issues a spurious warning on the call to std::advance here:
     158             : #pragma warning(push)
     159             : #pragma warning(disable:4244)
     160             : #endif
     161           0 :    inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::false_&)
     162             :    {
     163           0 :       if(i != j)
     164             :       {
     165           0 :          std::vector<char_type> v(i, j);
     166           0 :          const char_type* start = &v[0];
     167           0 :          const char_type* pos = start;
     168           0 :          int r = (int)m_traits.toi(pos, &v[0] + v.size(), base);
     169           0 :          std::advance(i, pos - start);
     170           0 :          return r;
     171             :       }
     172             :       return -1;
     173             :    }
     174             : #ifdef BOOST_MSVC
     175             : #pragma warning(pop)
     176             : #endif
     177             :    inline int toi(ForwardIter& i, ForwardIter j, int base, const boost::mpl::true_&)
     178             :    {
     179             :       return m_traits.toi(i, j, base);
     180             :    }
     181           0 :    inline int toi(ForwardIter& i, ForwardIter j, int base)
     182             :    {
     183             : #if defined(_MSC_VER) && defined(__INTEL_COMPILER) && ((__INTEL_COMPILER == 9999) || (__INTEL_COMPILER == 1210))
     184             :       // Workaround for Intel support issue #656654.
     185             :       // See also https://svn.boost.org/trac/boost/ticket/6359
     186             :       return toi(i, j, base, mpl::false_());
     187             : #else
     188             :       typedef typename boost::is_convertible<ForwardIter, const char_type*&>::type tag_type;
     189           0 :       return toi(i, j, base, tag_type());
     190             : #endif
     191             :    }
     192             : 
     193             :    const traits&    m_traits;       // the traits class for localised formatting operations
     194             :    const Results&   m_results;     // the match_results being used.
     195             :    OutputIterator   m_out;         // where to send output.
     196             :    ForwardIter      m_position;  // format string, current position
     197             :    ForwardIter      m_end;       // format string end
     198             :    match_flag_type  m_flags;      // format flags to use
     199             :    output_state     m_state;      // what to do with the next character
     200             :    output_state     m_restore_state;  // what state to restore to.
     201             :    bool             m_have_conditional; // we are parsing a conditional
     202             : private:
     203             :    basic_regex_formatter(const basic_regex_formatter&);
     204             :    basic_regex_formatter& operator=(const basic_regex_formatter&);
     205             : };
     206             : 
     207             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     208           0 : OutputIterator basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format(ForwardIter p1, ForwardIter p2, match_flag_type f)
     209             : {
     210           0 :    m_position = p1;
     211           0 :    m_end = p2;
     212           0 :    m_flags = f;
     213           0 :    format_all();
     214           0 :    return m_out;
     215             : }
     216             : 
     217             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     218           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_all()
     219             : {
     220             :    // over and over:
     221           0 :    while(m_position != m_end)
     222             :    {
     223           0 :       switch(*m_position)
     224             :       {
     225           0 :       case '&':
     226           0 :          if(m_flags & ::boost::regex_constants::format_sed)
     227             :          {
     228           0 :             ++m_position;
     229           0 :             put(m_results[0]);
     230             :             break;
     231             :          }
     232           0 :          put(*m_position++);
     233           0 :          break;
     234           0 :       case '\\':
     235           0 :          format_escape();
     236           0 :          break;
     237           0 :       case '(':
     238           0 :          if(m_flags & boost::regex_constants::format_all)
     239             :          {
     240           0 :             ++m_position;
     241           0 :             bool have_conditional = m_have_conditional;
     242           0 :             m_have_conditional = false;
     243           0 :             format_until_scope_end();
     244           0 :             m_have_conditional = have_conditional;
     245           0 :             if(m_position == m_end)
     246             :                return;
     247           0 :             BOOST_ASSERT(*m_position == static_cast<char_type>(')'));
     248           0 :             ++m_position;  // skip the closing ')'
     249           0 :             break;
     250             :          }
     251           0 :          put(*m_position);
     252           0 :          ++m_position;
     253           0 :          break;
     254           0 :       case ')':
     255           0 :          if(m_flags & boost::regex_constants::format_all)
     256             :          {
     257             :             return;
     258             :          }
     259           0 :          put(*m_position);
     260           0 :          ++m_position;
     261           0 :          break;
     262           0 :       case ':':
     263           0 :          if((m_flags & boost::regex_constants::format_all) && m_have_conditional)
     264             :          {
     265             :             return;
     266             :          }
     267           0 :          put(*m_position);
     268           0 :          ++m_position;
     269           0 :          break;
     270           0 :       case '?':
     271           0 :          if(m_flags & boost::regex_constants::format_all)
     272             :          {
     273           0 :             ++m_position;
     274           0 :             format_conditional();
     275           0 :             break;
     276             :          }
     277           0 :          put(*m_position);
     278           0 :          ++m_position;
     279           0 :          break;
     280           0 :       case '$':
     281           0 :          if((m_flags & format_sed) == 0)
     282             :          {
     283           0 :             format_perl();
     284           0 :             break;
     285             :          }
     286             :          // not a special character:
     287             :          BOOST_FALLTHROUGH;
     288             :       default:
     289           0 :          put(*m_position);
     290           0 :          ++m_position;
     291           0 :          break;
     292             :       }
     293             :    }
     294             : }
     295             : 
     296             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     297           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_perl()
     298             : {
     299             :    //
     300             :    // On entry *m_position points to a '$' character
     301             :    // output the information that goes with it:
     302             :    //
     303           0 :    BOOST_ASSERT(*m_position == '$');
     304             :    //
     305             :    // see if this is a trailing '$':
     306             :    //
     307           0 :    if(++m_position == m_end)
     308             :    {
     309           0 :       --m_position;
     310           0 :       put(*m_position);
     311           0 :       ++m_position;
     312           0 :       return;
     313             :    }
     314             :    //
     315             :    // OK find out what kind it is:
     316             :    //
     317           0 :    bool have_brace = false;
     318           0 :    ForwardIter save_position = m_position;
     319           0 :    switch(*m_position)
     320             :    {
     321           0 :    case '&':
     322           0 :       ++m_position;
     323           0 :       put(this->m_results[0]);
     324             :       break;
     325           0 :    case '`':
     326           0 :       ++m_position;
     327           0 :       put(this->m_results.prefix());
     328             :       break;
     329           0 :    case '\'':
     330           0 :       ++m_position;
     331           0 :       put(this->m_results.suffix());
     332             :       break;
     333           0 :    case '$':
     334           0 :       put(*m_position++);
     335           0 :       break;
     336           0 :    case '+':
     337           0 :       if((++m_position != m_end) && (*m_position == '{'))
     338             :       {
     339           0 :          ForwardIter base = ++m_position;
     340           0 :          while((m_position != m_end) && (*m_position != '}')) ++m_position;
     341           0 :          if(m_position != m_end)
     342             :          {
     343             :             // Named sub-expression:
     344           0 :             put(get_named_sub(base, m_position));
     345           0 :             ++m_position;
     346           0 :             break;
     347             :          }
     348             :          else
     349             :          {
     350           0 :             m_position = --base;
     351             :          }
     352             :       }
     353           0 :       put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
     354             :       break;
     355           0 :    case '{':
     356           0 :       have_brace = true;
     357           0 :       ++m_position;
     358             :       BOOST_FALLTHROUGH;
     359           0 :    default:
     360             :       // see if we have a number:
     361             :       {
     362           0 :          std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);
     363             :          //len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
     364           0 :          int v = this->toi(m_position, m_position + len, 10);
     365           0 :          if((v < 0) || (have_brace && ((m_position == m_end) || (*m_position != '}'))))
     366             :          {
     367             :             // Look for a Perl-5.10 verb:
     368           0 :             if(!handle_perl_verb(have_brace))
     369             :             {
     370             :                // leave the $ as is, and carry on:
     371           0 :                m_position = --save_position;
     372           0 :                put(*m_position);
     373           0 :                ++m_position;
     374             :             }
     375             :             break;
     376             :          }
     377             :          // otherwise output sub v:
     378           0 :          put(this->m_results[v]);
     379           0 :          if(have_brace)
     380           0 :             ++m_position;
     381             :       }
     382             :    }
     383             : }
     384             : 
     385             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     386           0 : bool basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::handle_perl_verb(bool have_brace)
     387             : {
     388             :    // 
     389             :    // We may have a capitalised string containing a Perl action:
     390             :    //
     391             :    static const char_type MATCH[] = { 'M', 'A', 'T', 'C', 'H' };
     392             :    static const char_type PREMATCH[] = { 'P', 'R', 'E', 'M', 'A', 'T', 'C', 'H' };
     393             :    static const char_type POSTMATCH[] = { 'P', 'O', 'S', 'T', 'M', 'A', 'T', 'C', 'H' };
     394             :    static const char_type LAST_PAREN_MATCH[] = { 'L', 'A', 'S', 'T', '_', 'P', 'A', 'R', 'E', 'N', '_', 'M', 'A', 'T', 'C', 'H' };
     395             :    static const char_type LAST_SUBMATCH_RESULT[] = { 'L', 'A', 'S', 'T', '_', 'S', 'U', 'B', 'M', 'A', 'T', 'C', 'H', '_', 'R', 'E', 'S', 'U', 'L', 'T' };
     396             :    static const char_type LAST_SUBMATCH_RESULT_ALT[] = { '^', 'N' };
     397             : 
     398           0 :    if(m_position == m_end)
     399             :       return false;
     400           0 :    if(have_brace && (*m_position == '^'))
     401           0 :       ++m_position;
     402             : 
     403           0 :    std::ptrdiff_t max_len = m_end - m_position;
     404             : 
     405           0 :    if((max_len >= 5) && std::equal(m_position, m_position + 5, MATCH))
     406             :    {
     407           0 :       m_position += 5;
     408           0 :       if(have_brace)
     409             :       {
     410           0 :          if((m_position != m_end) && (*m_position == '}'))
     411           0 :             ++m_position;
     412             :          else
     413             :          {
     414           0 :             m_position -= 5;
     415           0 :             return false;
     416             :          }
     417             :       }
     418           0 :       put(this->m_results[0]);
     419             :       return true;
     420             :    }
     421           0 :    if((max_len >= 8) && std::equal(m_position, m_position + 8, PREMATCH))
     422             :    {
     423           0 :       m_position += 8;
     424           0 :       if(have_brace)
     425             :       {
     426           0 :          if((m_position != m_end) && (*m_position == '}'))
     427           0 :             ++m_position;
     428             :          else
     429             :          {
     430           0 :             m_position -= 8;
     431           0 :             return false;
     432             :          }
     433             :       }
     434           0 :       put(this->m_results.prefix());
     435             :       return true;
     436             :    }
     437           0 :    if((max_len >= 9) && std::equal(m_position, m_position + 9, POSTMATCH))
     438             :    {
     439           0 :       m_position += 9;
     440           0 :       if(have_brace)
     441             :       {
     442           0 :          if((m_position != m_end) && (*m_position == '}'))
     443           0 :             ++m_position;
     444             :          else
     445             :          {
     446           0 :             m_position -= 9;
     447           0 :             return false;
     448             :          }
     449             :       }
     450           0 :       put(this->m_results.suffix());
     451             :       return true;
     452             :    }
     453           0 :    if((max_len >= 16) && std::equal(m_position, m_position + 16, LAST_PAREN_MATCH))
     454             :    {
     455           0 :       m_position += 16;
     456           0 :       if(have_brace)
     457             :       {
     458           0 :          if((m_position != m_end) && (*m_position == '}'))
     459           0 :             ++m_position;
     460             :          else
     461             :          {
     462           0 :             m_position -= 16;
     463           0 :             return false;
     464             :          }
     465             :       }
     466           0 :       put((this->m_results)[this->m_results.size() > 1 ? static_cast<int>(this->m_results.size() - 1) : 1]);
     467             :       return true;
     468             :    }
     469           0 :    if((max_len >= 20) && std::equal(m_position, m_position + 20, LAST_SUBMATCH_RESULT))
     470             :    {
     471           0 :       m_position += 20;
     472           0 :       if(have_brace)
     473             :       {
     474           0 :          if((m_position != m_end) && (*m_position == '}'))
     475           0 :             ++m_position;
     476             :          else
     477             :          {
     478           0 :             m_position -= 20;
     479           0 :             return false;
     480             :          }
     481             :       }
     482           0 :       put(this->m_results.get_last_closed_paren());
     483             :       return true;
     484             :    }
     485           0 :    if((max_len >= 2) && std::equal(m_position, m_position + 2, LAST_SUBMATCH_RESULT_ALT))
     486             :    {
     487           0 :       m_position += 2;
     488           0 :       if(have_brace)
     489             :       {
     490           0 :          if((m_position != m_end) && (*m_position == '}'))
     491           0 :             ++m_position;
     492             :          else
     493             :          {
     494           0 :             m_position -= 2;
     495           0 :             return false;
     496             :          }
     497             :       }
     498           0 :       put(this->m_results.get_last_closed_paren());
     499             :       return true;
     500             :    }
     501             :    return false;
     502             : }
     503             : 
     504             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     505           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_escape()
     506             : {
     507             :    // skip the escape and check for trailing escape:
     508           0 :    if(++m_position == m_end)
     509             :    {
     510           0 :       put(static_cast<char_type>('\\'));
     511           0 :       return;
     512             :    }
     513             :    // now switch on the escape type:
     514           0 :    switch(*m_position)
     515             :    {
     516           0 :    case 'a':
     517           0 :       put(static_cast<char_type>('\a'));
     518           0 :       ++m_position;
     519           0 :       break;
     520           0 :    case 'f':
     521           0 :       put(static_cast<char_type>('\f'));
     522           0 :       ++m_position;
     523           0 :       break;
     524           0 :    case 'n':
     525           0 :       put(static_cast<char_type>('\n'));
     526           0 :       ++m_position;
     527           0 :       break;
     528           0 :    case 'r':
     529           0 :       put(static_cast<char_type>('\r'));
     530           0 :       ++m_position;
     531           0 :       break;
     532           0 :    case 't':
     533           0 :       put(static_cast<char_type>('\t'));
     534           0 :       ++m_position;
     535           0 :       break;
     536           0 :    case 'v':
     537           0 :       put(static_cast<char_type>('\v'));
     538           0 :       ++m_position;
     539           0 :       break;
     540           0 :    case 'x':
     541           0 :       if(++m_position == m_end)
     542             :       {
     543           0 :          put(static_cast<char_type>('x'));
     544           0 :          return;
     545             :       }
     546             :       // maybe have \x{ddd}
     547           0 :       if(*m_position == static_cast<char_type>('{'))
     548             :       {
     549           0 :          ++m_position;
     550           0 :          int val = this->toi(m_position, m_end, 16);
     551           0 :          if(val < 0)
     552             :          {
     553             :             // invalid value treat everything as literals:
     554           0 :             put(static_cast<char_type>('x'));
     555           0 :             put(static_cast<char_type>('{'));
     556           0 :             return;
     557             :          }
     558           0 :          if((m_position == m_end) || (*m_position != static_cast<char_type>('}')))
     559             :          {
     560           0 :             --m_position;
     561           0 :             while(*m_position != static_cast<char_type>('\\'))
     562           0 :                --m_position;
     563           0 :             ++m_position;
     564           0 :             put(*m_position++);
     565           0 :             return;
     566             :          }
     567           0 :          ++m_position;
     568           0 :          put(static_cast<char_type>(val));
     569           0 :          return;
     570             :       }
     571             :       else
     572             :       {
     573           0 :          std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);
     574           0 :          len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
     575           0 :          int val = this->toi(m_position, m_position + len, 16);
     576           0 :          if(val < 0)
     577             :          {
     578           0 :             --m_position;
     579           0 :             put(*m_position++);
     580           0 :             return;
     581             :          }
     582           0 :          put(static_cast<char_type>(val));
     583             :       }
     584           0 :       break;
     585           0 :    case 'c':
     586           0 :       if(++m_position == m_end)
     587             :       {
     588             :          --m_position;
     589           0 :          put(*m_position++);
     590           0 :          return;
     591             :       }
     592           0 :       put(static_cast<char_type>(*m_position++ % 32));
     593             :       break;
     594           0 :    case 'e':
     595           0 :       put(static_cast<char_type>(27));
     596           0 :       ++m_position;
     597           0 :       break;
     598           0 :    default:
     599             :       // see if we have a perl specific escape:
     600           0 :       if((m_flags & boost::regex_constants::format_sed) == 0)
     601             :       {
     602           0 :          bool breakout = false;
     603             :          switch(*m_position)
     604             :          {
     605           0 :          case 'l':
     606           0 :             ++m_position;
     607           0 :             m_restore_state = m_state;
     608           0 :             m_state = output_next_lower;
     609             :             breakout = true;
     610             :             break;
     611           0 :          case 'L':
     612           0 :             ++m_position;
     613           0 :             m_state = output_lower;
     614             :             breakout = true;
     615             :             break;
     616           0 :          case 'u':
     617           0 :             ++m_position;
     618           0 :             m_restore_state = m_state;
     619           0 :             m_state = output_next_upper;
     620             :             breakout = true;
     621             :             break;
     622           0 :          case 'U':
     623           0 :             ++m_position;
     624           0 :             m_state = output_upper;
     625             :             breakout = true;
     626             :             break;
     627           0 :          case 'E':
     628           0 :             ++m_position;
     629           0 :             m_state = output_copy;
     630             :             breakout = true;
     631             :             break;
     632             :          }
     633             :          if(breakout)
     634             :             break;
     635             :       }
     636             :       // see if we have a \n sed style backreference:
     637           0 :       std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);
     638           0 :       len = (std::min)(static_cast<std::ptrdiff_t>(1), len);
     639           0 :       int v = this->toi(m_position, m_position+len, 10);
     640           0 :       if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))
     641             :       {
     642           0 :          put(m_results[v]);
     643             :          break;
     644             :       }
     645           0 :       else if(v == 0)
     646             :       {
     647             :          // octal ecape sequence:
     648           0 :          --m_position;
     649           0 :          len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);
     650           0 :          len = (std::min)(static_cast<std::ptrdiff_t>(4), len);
     651           0 :          v = this->toi(m_position, m_position + len, 8);
     652           0 :          BOOST_ASSERT(v >= 0);
     653           0 :          put(static_cast<char_type>(v));
     654             :          break;
     655             :       }
     656             :       // Otherwise output the character "as is":
     657           0 :       put(*m_position++);
     658             :       break;
     659             :    }
     660             : }
     661             : 
     662             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     663           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_conditional()
     664             : {
     665           0 :    if(m_position == m_end)
     666             :    {
     667             :       // oops trailing '?':
     668           0 :       put(static_cast<char_type>('?'));
     669           0 :       return;
     670             :    }
     671             :    int v;
     672           0 :    if(*m_position == '{')
     673             :    {
     674           0 :       ForwardIter base = m_position;
     675           0 :       ++m_position;
     676           0 :       v = this->toi(m_position, m_end, 10);
     677           0 :       if(v < 0)
     678             :       {
     679             :          // Try a named subexpression:
     680           0 :          while((m_position != m_end) && (*m_position != '}'))
     681           0 :             ++m_position;
     682           0 :          v = this->get_named_sub_index(base + 1, m_position);
     683             :       }
     684           0 :       if((v < 0) || (*m_position != '}'))
     685             :       {
     686           0 :          m_position = base;
     687             :          // oops trailing '?':
     688           0 :          put(static_cast<char_type>('?'));
     689           0 :          return;
     690             :       }
     691             :       // Skip trailing '}':
     692           0 :       ++m_position;
     693             :    }
     694             :    else
     695             :    {
     696           0 :       std::ptrdiff_t len = ::boost::BOOST_REGEX_DETAIL_NS::distance(m_position, m_end);
     697           0 :       len = (std::min)(static_cast<std::ptrdiff_t>(2), len);
     698           0 :       v = this->toi(m_position, m_position + len, 10);
     699             :    }
     700           0 :    if(v < 0)
     701             :    {
     702             :       // oops not a number:
     703           0 :       put(static_cast<char_type>('?'));
     704           0 :       return;
     705             :    }
     706             : 
     707             :    // output varies depending upon whether sub-expression v matched or not:
     708           0 :    if(m_results[v].matched)
     709             :    {
     710           0 :       m_have_conditional = true;
     711           0 :       format_all();
     712           0 :       m_have_conditional = false;
     713           0 :       if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
     714             :       {
     715             :          // skip the ':':
     716           0 :          ++m_position;
     717             :          // save output state, then turn it off:
     718           0 :          output_state saved_state = m_state;
     719           0 :          m_state = output_none;
     720             :          // format the rest of this scope:
     721           0 :          format_until_scope_end();
     722             :          // restore output state:
     723           0 :          m_state = saved_state;
     724             :       }
     725             :    }
     726             :    else
     727             :    {
     728             :       // save output state, then turn it off:
     729           0 :       output_state saved_state = m_state;
     730           0 :       m_state = output_none;
     731             :       // format until ':' or ')':
     732           0 :       m_have_conditional = true;
     733           0 :       format_all();
     734           0 :       m_have_conditional = false;
     735             :       // restore state:
     736           0 :       m_state = saved_state;
     737           0 :       if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
     738             :       {
     739             :          // skip the ':':
     740           0 :          ++m_position;
     741             :          // format the rest of this scope:
     742           0 :          format_until_scope_end();
     743             :       }
     744             :    }
     745             : }
     746             : 
     747             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     748           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::format_until_scope_end()
     749             : {
     750             :    do
     751             :    {
     752           0 :       format_all();
     753           0 :       if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
     754             :          return;
     755           0 :       put(*m_position++);
     756           0 :    }while(m_position != m_end);
     757             : }
     758             : 
     759             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     760           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(char_type c)
     761             : {
     762             :    // write a single character to output
     763             :    // according to which case translation mode we are in:
     764           0 :    switch(this->m_state)
     765             :    {
     766             :    case output_none:
     767             :       return;
     768           0 :    case output_next_lower:
     769           0 :       c = m_traits.tolower(c);
     770           0 :       this->m_state = m_restore_state;
     771           0 :       break;
     772           0 :    case output_next_upper:
     773           0 :       c = m_traits.toupper(c);
     774           0 :       this->m_state = m_restore_state;
     775           0 :       break;
     776           0 :    case output_lower:
     777           0 :       c = m_traits.tolower(c);
     778           0 :       break;
     779           0 :    case output_upper:
     780           0 :       c = m_traits.toupper(c);
     781           0 :       break;
     782             :    default:
     783             :       break;
     784             :    }
     785           0 :    *m_out = c;
     786           0 :    ++m_out;
     787             : }
     788             : 
     789             : template <class OutputIterator, class Results, class traits, class ForwardIter>
     790           0 : void basic_regex_formatter<OutputIterator, Results, traits, ForwardIter>::put(const sub_match_type& sub)
     791             : {
     792             :    typedef typename sub_match_type::iterator iterator_type;
     793           0 :    iterator_type i = sub.first;
     794           0 :    while(i != sub.second)
     795             :    {
     796           0 :       put(*i);
     797           0 :       ++i;
     798             :    }
     799             : }
     800             : 
     801             : template <class S>
     802             : class string_out_iterator
     803             : {
     804             :    S* out;
     805             : public:
     806             :    string_out_iterator(S& s) : out(&s) {}
     807             :    string_out_iterator& operator++() { return *this; }
     808             :    string_out_iterator& operator++(int) { return *this; }
     809             :    string_out_iterator& operator*() { return *this; }
     810             :    string_out_iterator& operator=(typename S::value_type v) 
     811             :    { 
     812             :       out->append(1, v); 
     813             :       return *this; 
     814             :    }
     815             : 
     816             :    typedef std::ptrdiff_t difference_type;
     817             :    typedef typename S::value_type value_type;
     818             :    typedef value_type* pointer;
     819             :    typedef value_type& reference;
     820             :    typedef std::output_iterator_tag iterator_category;
     821             : };
     822             : 
     823             : template <class OutputIterator, class Iterator, class Alloc, class ForwardIter, class traits>
     824           0 : OutputIterator regex_format_imp(OutputIterator out,
     825             :                           const match_results<Iterator, Alloc>& m,
     826             :                           ForwardIter p1, ForwardIter p2,
     827             :                           match_flag_type flags,
     828             :                           const traits& t
     829             :                          )
     830             : {
     831           0 :    if(flags & regex_constants::format_literal)
     832             :    {
     833           0 :       return BOOST_REGEX_DETAIL_NS::copy(p1, p2, out);
     834             :    }
     835             : 
     836             :    BOOST_REGEX_DETAIL_NS::basic_regex_formatter<
     837             :       OutputIterator, 
     838             :       match_results<Iterator, Alloc>, 
     839           0 :       traits, ForwardIter> f(out, m, t);
     840           0 :    return f.format(p1, p2, flags);
     841             : }
     842             : 
     843             : #ifndef BOOST_NO_SFINAE
     844             : 
     845             : BOOST_MPL_HAS_XXX_TRAIT_DEF(const_iterator)
     846             : 
     847             : struct any_type 
     848             : {
     849             :    template <class T>
     850             :    any_type(const T&); 
     851             :    template <class T, class U>
     852             :    any_type(const T&, const U&); 
     853             :    template <class T, class U, class V>
     854             :    any_type(const T&, const U&, const V&); 
     855             : };
     856             : typedef char no_type;
     857             : typedef char (&unary_type)[2];
     858             : typedef char (&binary_type)[3];
     859             : typedef char (&ternary_type)[4];
     860             : 
     861             : no_type check_is_formatter(unary_type, binary_type, ternary_type);
     862             : template<typename T>
     863             : unary_type check_is_formatter(T const &, binary_type, ternary_type);
     864             : template<typename T>
     865             : binary_type check_is_formatter(unary_type, T const &, ternary_type);
     866             : template<typename T, typename U>
     867             : binary_type check_is_formatter(T const &, U const &, ternary_type);
     868             : template<typename T>
     869             : ternary_type check_is_formatter(unary_type, binary_type, T const &);
     870             : template<typename T, typename U>
     871             : ternary_type check_is_formatter(T const &, binary_type, U const &);
     872             : template<typename T, typename U>
     873             : ternary_type check_is_formatter(unary_type, T const &, U const &);
     874             : template<typename T, typename U, typename V>
     875             : ternary_type check_is_formatter(T const &, U const &, V const &);
     876             : 
     877             : struct unary_binary_ternary
     878             : {
     879             :     typedef unary_type (*unary_fun)(any_type);
     880             :     typedef binary_type (*binary_fun)(any_type, any_type);
     881             :     typedef ternary_type (*ternary_fun)(any_type, any_type, any_type);
     882             :     operator unary_fun();
     883             :     operator binary_fun();
     884             :     operator ternary_fun();
     885             : };
     886             : 
     887             : template<typename Formatter, bool IsFunction = boost::is_function<Formatter>::value>
     888             : struct formatter_wrapper
     889             :   : Formatter
     890             :   , unary_binary_ternary
     891             : {
     892             :    formatter_wrapper(){}
     893             : };
     894             : 
     895             : template<typename Formatter>
     896             : struct formatter_wrapper<Formatter, true>
     897             :   : unary_binary_ternary
     898             : {
     899             :     operator Formatter *();
     900             : };
     901             : 
     902             : template<typename Formatter>
     903             : struct formatter_wrapper<Formatter *, false>
     904             :   : unary_binary_ternary
     905             : {
     906             :     operator Formatter *();
     907             : };
     908             : 
     909             : template <class F, class M, class O>
     910             : struct format_traits_imp
     911             : {
     912             : private:
     913             :    //
     914             :    // F must be a pointer, a function, or a class with a function call operator:
     915             :    //
     916             :    BOOST_STATIC_ASSERT((::boost::is_pointer<F>::value || ::boost::is_function<F>::value || ::boost::is_class<F>::value));
     917             :    static formatter_wrapper<typename unwrap_reference<F>::type> f;
     918             :    static M m;
     919             :    static O out;
     920             :    static boost::regex_constants::match_flag_type flags;
     921             : public:
     922             :    BOOST_STATIC_CONSTANT(int, value = sizeof(check_is_formatter(f(m), f(m, out), f(m, out, flags))));
     923             : };
     924             : 
     925             : template <class F, class M, class O>
     926             : struct format_traits
     927             : {
     928             : public:
     929             :    // 
     930             :    // Type is mpl::int_<N> where N is one of:
     931             :    //
     932             :    // 0 : F is a pointer to a presumably null-terminated string.
     933             :    // 1 : F is a character-container such as a std::string.
     934             :    // 2 : F is a Unary Functor.
     935             :    // 3 : F is a Binary Functor.
     936             :    // 4 : F is a Ternary Functor.
     937             :    //
     938             :    typedef typename boost::mpl::if_<
     939             :       boost::mpl::and_<boost::is_pointer<F>, boost::mpl::not_<boost::is_function<typename boost::remove_pointer<F>::type> > >,
     940             :       boost::mpl::int_<0>,
     941             :       typename boost::mpl::if_<
     942             :          has_const_iterator<F>,
     943             :          boost::mpl::int_<1>,
     944             :          boost::mpl::int_<format_traits_imp<F, M, O>::value>
     945             :       >::type
     946             :    >::type type;
     947             :    //
     948             :    // This static assertion will fail if the functor passed does not accept
     949             :    // the same type of arguments passed.
     950             :    //
     951             :    BOOST_STATIC_ASSERT( boost::is_class<F>::value && !has_const_iterator<F>::value ? (type::value > 1) : true);
     952             : };
     953             : 
     954             : #else // BOOST_NO_SFINAE
     955             : 
     956             : template <class F, class M, class O>
     957             : struct format_traits
     958             : {
     959             : public:
     960             :    // 
     961             :    // Type is mpl::int_<N> where N is one of:
     962             :    //
     963             :    // 0 : F is a pointer to a presumably null-terminated string.
     964             :    // 1 : F is a character-container such as a std::string.
     965             :    //
     966             :    // Other options such as F being a Functor are not supported without
     967             :    // SFINAE support.
     968             :    //
     969             :    typedef typename boost::mpl::if_<
     970             :       boost::is_pointer<F>,
     971             :       boost::mpl::int_<0>,
     972             :       boost::mpl::int_<1>
     973             :    >::type type;
     974             : };
     975             : 
     976             : #endif // BOOST_NO_SFINAE
     977             : 
     978             : template <class Base, class Match>
     979             : struct format_functor3
     980             : {
     981             :    format_functor3(Base b) : func(b) {}
     982             :    template <class OutputIter>
     983             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f)
     984             :    {
     985             :       return boost::unwrap_ref(func)(m, i, f);
     986             :    }
     987             :    template <class OutputIter, class Traits>
     988             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
     989             :    {
     990             :       return (*this)(m, i, f);
     991             :    }
     992             : private:
     993             :    Base func;
     994             :    format_functor3(const format_functor3&);
     995             :    format_functor3& operator=(const format_functor3&);
     996             : };
     997             : 
     998             : template <class Base, class Match>
     999             : struct format_functor2
    1000             : {
    1001             :    format_functor2(Base b) : func(b) {}
    1002             :    template <class OutputIter>
    1003             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
    1004             :    {
    1005             :       return boost::unwrap_ref(func)(m, i);
    1006             :    }
    1007             :    template <class OutputIter, class Traits>
    1008             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
    1009             :    {
    1010             :       return (*this)(m, i, f);
    1011             :    }
    1012             : private:
    1013             :    Base func;
    1014             :    format_functor2(const format_functor2&);
    1015             :    format_functor2& operator=(const format_functor2&);
    1016             : };
    1017             : 
    1018             : template <class Base, class Match>
    1019             : struct format_functor1
    1020             : {
    1021             :    format_functor1(Base b) : func(b) {}
    1022             : 
    1023             :    template <class S, class OutputIter>
    1024             :    OutputIter do_format_string(const S& s, OutputIter i)
    1025             :    {
    1026             :       return BOOST_REGEX_DETAIL_NS::copy(s.begin(), s.end(), i);
    1027             :    }
    1028             :    template <class S, class OutputIter>
    1029             :    inline OutputIter do_format_string(const S* s, OutputIter i)
    1030             :    {
    1031             :       while(s && *s)
    1032             :       {
    1033             :          *i = *s;
    1034             :          ++i;
    1035             :          ++s;
    1036             :       }
    1037             :       return i;
    1038             :    }
    1039             :    template <class OutputIter>
    1040             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type /*f*/)
    1041             :    {
    1042             :       return do_format_string(boost::unwrap_ref(func)(m), i);
    1043             :    }
    1044             :    template <class OutputIter, class Traits>
    1045             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits&)
    1046             :    {
    1047             :       return (*this)(m, i, f);
    1048             :    }
    1049             : private:
    1050             :    Base func;
    1051             :    format_functor1(const format_functor1&);
    1052             :    format_functor1& operator=(const format_functor1&);
    1053             : };
    1054             : 
    1055             : template <class charT, class Match, class Traits>
    1056             : struct format_functor_c_string
    1057             : {
    1058             :    format_functor_c_string(const charT* ps) : func(ps) {}
    1059             : 
    1060             :    template <class OutputIter>
    1061             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())
    1062             :    {
    1063             :       //typedef typename Match::char_type char_type;
    1064             :       const charT* end = func;
    1065             :       while(*end) ++end;
    1066             :       return regex_format_imp(i, m, func, end, f, t);
    1067             :    }
    1068             : private:
    1069             :    const charT* func;
    1070             :    format_functor_c_string(const format_functor_c_string&);
    1071             :    format_functor_c_string& operator=(const format_functor_c_string&);
    1072             : };
    1073             : 
    1074             : template <class Container, class Match, class Traits>
    1075             : struct format_functor_container
    1076             : {
    1077             :    format_functor_container(const Container& c) : func(c) {}
    1078             : 
    1079             :    template <class OutputIter>
    1080             :    OutputIter operator()(const Match& m, OutputIter i, boost::regex_constants::match_flag_type f, const Traits& t = Traits())
    1081             :    {
    1082             :       //typedef typename Match::char_type char_type;
    1083             :       return BOOST_REGEX_DETAIL_NS::regex_format_imp(i, m, func.begin(), func.end(), f, t);
    1084             :    }
    1085             : private:
    1086             :    const Container& func;
    1087             :    format_functor_container(const format_functor_container&);
    1088             :    format_functor_container& operator=(const format_functor_container&);
    1089             : };
    1090             : 
    1091             : template <class Func, class Match, class OutputIterator, class Traits = BOOST_REGEX_DETAIL_NS::trivial_format_traits<typename Match::char_type> >
    1092             : struct compute_functor_type
    1093             : {
    1094             :    typedef typename format_traits<Func, Match, OutputIterator>::type tag;
    1095             :    typedef typename boost::remove_cv< typename boost::remove_pointer<Func>::type>::type maybe_char_type;
    1096             : 
    1097             :    typedef typename mpl::if_<
    1098             :       ::boost::is_same<tag, mpl::int_<0> >, format_functor_c_string<maybe_char_type, Match, Traits>,
    1099             :       typename mpl::if_<
    1100             :          ::boost::is_same<tag, mpl::int_<1> >, format_functor_container<Func, Match, Traits>,
    1101             :          typename mpl::if_<
    1102             :             ::boost::is_same<tag, mpl::int_<2> >, format_functor1<Func, Match>,
    1103             :             typename mpl::if_<
    1104             :                ::boost::is_same<tag, mpl::int_<3> >, format_functor2<Func, Match>, 
    1105             :                format_functor3<Func, Match>
    1106             :             >::type
    1107             :          >::type
    1108             :       >::type
    1109             :    >::type type;
    1110             : };
    1111             : 
    1112             : } // namespace BOOST_REGEX_DETAIL_NS
    1113             : 
    1114             : template <class OutputIterator, class Iterator, class Allocator, class Functor>
    1115             : inline OutputIterator regex_format(OutputIterator out,
    1116             :                           const match_results<Iterator, Allocator>& m,
    1117             :                           Functor fmt,
    1118             :                           match_flag_type flags = format_all
    1119             :                          )
    1120             : {
    1121             :    return m.format(out, fmt, flags);
    1122             : }
    1123             : 
    1124             : template <class Iterator, class Allocator, class Functor>
    1125             : inline std::basic_string<typename match_results<Iterator, Allocator>::char_type> regex_format(const match_results<Iterator, Allocator>& m, 
    1126             :                                       Functor fmt, 
    1127             :                                       match_flag_type flags = format_all)
    1128             : {
    1129             :    return m.format(fmt, flags);
    1130             : }
    1131             : 
    1132             : #ifdef BOOST_MSVC
    1133             : #pragma warning(push)
    1134             : #pragma warning(disable: 4103)
    1135             : #endif
    1136             : #ifdef BOOST_HAS_ABI_HEADERS
    1137             : #  include BOOST_ABI_SUFFIX
    1138             : #endif
    1139             : #ifdef BOOST_MSVC
    1140             : #pragma warning(pop)
    1141             : #endif
    1142             : 
    1143             : } // namespace boost
    1144             : 
    1145             : #endif  // BOOST_REGEX_FORMAT_HPP
    1146             : 
    1147             : 
    1148             : 
    1149             : 
    1150             : 
    1151             : 

Generated by: LCOV version 1.14