Coverage Report

Created: 2025-01-19 07:38

/src/boost/boost/regex/v5/basic_regex_parser.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *
3
 * Copyright (c) 2004
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         basic_regex_parser.cpp
15
  *   VERSION      see <boost/version.hpp>
16
  *   DESCRIPTION: Declares template class basic_regex_parser.
17
  */
18
19
#ifndef BOOST_REGEX_V5_BASIC_REGEX_PARSER_HPP
20
#define BOOST_REGEX_V5_BASIC_REGEX_PARSER_HPP
21
22
namespace boost{
23
namespace BOOST_REGEX_DETAIL_NS{
24
25
#ifdef BOOST_REGEX_MSVC
26
#pragma warning(push)
27
#pragma warning(disable:4244 4459)
28
#if BOOST_REGEX_MSVC < 1910
29
#pragma warning(disable:4800)
30
#endif
31
#endif
32
33
inline std::intmax_t umax(std::integral_constant<bool, false> const&)
34
11.4k
{
35
   // Get out clause here, just in case numeric_limits is unspecialized:
36
11.4k
   return std::numeric_limits<std::intmax_t>::is_specialized ? (std::numeric_limits<std::intmax_t>::max)() : INT_MAX;
37
11.4k
}
38
inline std::intmax_t umax(std::integral_constant<bool, true> const&)
39
0
{
40
0
   return (std::numeric_limits<std::size_t>::max)();
41
0
}
42
43
inline std::intmax_t umax()
44
11.4k
{
45
11.4k
   return umax(std::integral_constant<bool, std::numeric_limits<std::intmax_t>::digits >= std::numeric_limits<std::size_t>::digits>());
46
11.4k
}
47
48
template <class charT, class traits>
49
class basic_regex_parser : public basic_regex_creator<charT, traits>
50
{
51
public:
52
   basic_regex_parser(regex_data<charT, traits>* data);
53
   void parse(const charT* p1, const charT* p2, unsigned flags);
54
   void fail(regex_constants::error_type error_code, std::ptrdiff_t position);
55
   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos);
56
   void fail(regex_constants::error_type error_code, std::ptrdiff_t position, const std::string& message)
57
162
   {
58
162
      fail(error_code, position, message, position);
59
162
   }
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
57
162
   {
58
162
      fail(error_code, position, message, position);
59
162
   }
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
60
61
   bool parse_all();
62
   bool parse_basic();
63
   bool parse_extended();
64
   bool parse_literal();
65
   bool parse_open_paren();
66
   bool parse_basic_escape();
67
   bool parse_extended_escape();
68
   bool parse_match_any();
69
   bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());
70
   bool parse_repeat_range(bool isbasic);
71
   bool parse_alt();
72
   bool parse_set();
73
   bool parse_backref();
74
   void parse_set_literal(basic_char_set<charT, traits>& char_set);
75
   bool parse_inner_set(basic_char_set<charT, traits>& char_set);
76
   bool parse_QE();
77
   bool parse_perl_extension();
78
   bool parse_perl_verb();
79
   bool match_verb(const char*);
80
   bool add_emacs_code(bool negate);
81
   bool unwind_alts(std::ptrdiff_t last_paren_start);
82
   digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);
83
   charT unescape_character();
84
   regex_constants::syntax_option_type parse_options();
85
86
private:
87
   typedef bool (basic_regex_parser::*parser_proc_type)();
88
   typedef typename traits::string_type string_type;
89
   typedef typename traits::char_class_type char_class_type;
90
   parser_proc_type           m_parser_proc;    // the main parser to use
91
   const charT*               m_base;           // the start of the string being parsed
92
   const charT*               m_end;            // the end of the string being parsed
93
   const charT*               m_position;       // our current parser position
94
   unsigned                   m_mark_count;     // how many sub-expressions we have
95
   int                        m_mark_reset;     // used to indicate that we're inside a (?|...) block.
96
   unsigned                   m_max_mark;       // largest mark count seen inside a (?|...) block.
97
   std::ptrdiff_t             m_paren_start;    // where the last seen ')' began (where repeats are inserted).
98
   std::ptrdiff_t             m_alt_insert_point; // where to insert the next alternative
99
   bool                       m_has_case_change; // true if somewhere in the current block the case has changed
100
   unsigned                   m_recursion_count; // How many times we've called parse_all.
101
   unsigned                   m_max_backref;     // Largest index of any backref.
102
#if defined(BOOST_REGEX_MSVC) && defined(_M_IX86)
103
   // This is an ugly warning suppression workaround (for warnings *inside* std::vector
104
   // that can not otherwise be suppressed)...
105
   static_assert(sizeof(long) >= sizeof(void*), "Long isn't long enough!");
106
   std::vector<long>           m_alt_jumps;      // list of alternative in the current scope.
107
#else
108
   std::vector<std::ptrdiff_t> m_alt_jumps;      // list of alternative in the current scope.
109
#endif
110
111
   basic_regex_parser& operator=(const basic_regex_parser&);
112
   basic_regex_parser(const basic_regex_parser&);
113
};
114
115
template <class charT, class traits>
116
basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
117
36.9k
   : basic_regex_creator<charT, traits>(data), m_parser_proc(), m_base(0), m_end(0), m_position(0), 
118
36.9k
   m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0), m_max_backref(0)
119
36.9k
{
120
36.9k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::basic_regex_parser(boost::re_detail_500::regex_data<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >*)
Line
Count
Source
117
36.9k
   : basic_regex_creator<charT, traits>(data), m_parser_proc(), m_base(0), m_end(0), m_position(0), 
118
36.9k
   m_mark_count(0), m_mark_reset(-1), m_max_mark(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false), m_recursion_count(0), m_max_backref(0)
119
36.9k
{
120
36.9k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::basic_regex_parser(boost::re_detail_500::regex_data<char, boost::c_regex_traits<char> >*)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::basic_regex_parser(boost::re_detail_500::regex_data<wchar_t, boost::c_regex_traits<wchar_t> >*)
121
122
template <class charT, class traits>
123
void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned l_flags)
124
36.9k
{
125
   // pass l_flags on to base class:
126
36.9k
   this->init(l_flags);
127
   // set up pointers:
128
36.9k
   m_position = m_base = p1;
129
36.9k
   m_end = p2;
130
   // empty strings are errors:
131
36.9k
   if((p1 == p2) && 
132
36.9k
      (
133
38
         ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)
134
38
         || (l_flags & regbase::no_empty_expressions)
135
38
      )
136
36.9k
     )
137
0
   {
138
0
      fail(regex_constants::error_empty, 0);
139
0
      return;
140
0
   }
141
   // select which parser to use:
142
36.9k
   switch(l_flags & regbase::main_option_type)
143
36.9k
   {
144
36.9k
   case regbase::perl_syntax_group:
145
36.9k
      {
146
36.9k
         m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;
147
         //
148
         // Add a leading paren with index zero to give recursions a target:
149
         //
150
36.9k
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
151
36.9k
         br->index = 0;
152
36.9k
         br->icase = this->flags() & regbase::icase;
153
36.9k
         break;
154
0
      }
155
0
   case regbase::basic_syntax_group:
156
0
      m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;
157
0
      break;
158
0
   case regbase::literal:
159
0
      m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;
160
0
      break;
161
0
   default:
162
      // Oops, someone has managed to set more than one of the main option flags, 
163
      // so this must be an error:
164
0
      fail(regex_constants::error_unknown, 0, "An invalid combination of regular expression syntax flags was used.");
165
0
      return;
166
36.9k
   }
167
168
   // parse all our characters:
169
36.9k
   bool result = parse_all();
170
   //
171
   // Unwind our alternatives:
172
   //
173
36.9k
   unwind_alts(-1);
174
   // reset l_flags as a global scope (?imsx) may have altered them:
175
36.9k
   this->flags(l_flags);
176
   // if we haven't gobbled up all the characters then we must
177
   // have had an unexpected ')' :
178
36.9k
   if(!result)
179
13
   {
180
13
      fail(regex_constants::error_paren, std::distance(m_base, m_position), "Found a closing ) with no corresponding opening parenthesis.");
181
13
      return;
182
13
   }
183
   // if an error has been set then give up now:
184
36.9k
   if(this->m_pdata->m_status)
185
0
      return;
186
   // fill in our sub-expression count:
187
36.9k
   this->m_pdata->m_mark_count = 1u + (std::size_t)m_mark_count;
188
   //
189
   // Check we don't have backreferences to sub-expressions which don't exist:
190
   //
191
36.9k
   if (m_max_backref > m_mark_count)
192
2
   {
193
2
      fail(regex_constants::error_backref, std::distance(m_base, m_position), "Found a backreference to a non-existant sub-expression.");
194
2
   }
195
36.9k
   this->finalize(p1, p2);
196
36.9k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse(char const*, char const*, unsigned int)
Line
Count
Source
124
36.9k
{
125
   // pass l_flags on to base class:
126
36.9k
   this->init(l_flags);
127
   // set up pointers:
128
36.9k
   m_position = m_base = p1;
129
36.9k
   m_end = p2;
130
   // empty strings are errors:
131
36.9k
   if((p1 == p2) && 
132
36.9k
      (
133
38
         ((l_flags & regbase::main_option_type) != regbase::perl_syntax_group)
134
38
         || (l_flags & regbase::no_empty_expressions)
135
38
      )
136
36.9k
     )
137
0
   {
138
0
      fail(regex_constants::error_empty, 0);
139
0
      return;
140
0
   }
141
   // select which parser to use:
142
36.9k
   switch(l_flags & regbase::main_option_type)
143
36.9k
   {
144
36.9k
   case regbase::perl_syntax_group:
145
36.9k
      {
146
36.9k
         m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;
147
         //
148
         // Add a leading paren with index zero to give recursions a target:
149
         //
150
36.9k
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
151
36.9k
         br->index = 0;
152
36.9k
         br->icase = this->flags() & regbase::icase;
153
36.9k
         break;
154
0
      }
155
0
   case regbase::basic_syntax_group:
156
0
      m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;
157
0
      break;
158
0
   case regbase::literal:
159
0
      m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;
160
0
      break;
161
0
   default:
162
      // Oops, someone has managed to set more than one of the main option flags, 
163
      // so this must be an error:
164
0
      fail(regex_constants::error_unknown, 0, "An invalid combination of regular expression syntax flags was used.");
165
0
      return;
166
36.9k
   }
167
168
   // parse all our characters:
169
36.9k
   bool result = parse_all();
170
   //
171
   // Unwind our alternatives:
172
   //
173
36.9k
   unwind_alts(-1);
174
   // reset l_flags as a global scope (?imsx) may have altered them:
175
36.9k
   this->flags(l_flags);
176
   // if we haven't gobbled up all the characters then we must
177
   // have had an unexpected ')' :
178
36.9k
   if(!result)
179
13
   {
180
13
      fail(regex_constants::error_paren, std::distance(m_base, m_position), "Found a closing ) with no corresponding opening parenthesis.");
181
13
      return;
182
13
   }
183
   // if an error has been set then give up now:
184
36.9k
   if(this->m_pdata->m_status)
185
0
      return;
186
   // fill in our sub-expression count:
187
36.9k
   this->m_pdata->m_mark_count = 1u + (std::size_t)m_mark_count;
188
   //
189
   // Check we don't have backreferences to sub-expressions which don't exist:
190
   //
191
36.9k
   if (m_max_backref > m_mark_count)
192
2
   {
193
2
      fail(regex_constants::error_backref, std::distance(m_base, m_position), "Found a backreference to a non-existant sub-expression.");
194
2
   }
195
36.9k
   this->finalize(p1, p2);
196
36.9k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse(char const*, char const*, unsigned int)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse(wchar_t const*, wchar_t const*, unsigned int)
197
198
template <class charT, class traits>
199
void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)
200
122
{
201
   // get the error message:
202
122
   std::string message = this->m_pdata->m_ptraits->error_string(error_code);
203
122
   fail(error_code, position, message);
204
122
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::fail(boost::regex_constants::error_type, long)
Line
Count
Source
200
122
{
201
   // get the error message:
202
122
   std::string message = this->m_pdata->m_ptraits->error_string(error_code);
203
122
   fail(error_code, position, message);
204
122
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::fail(boost::regex_constants::error_type, long)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::fail(boost::regex_constants::error_type, long)
205
206
template <class charT, class traits>
207
void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position, std::string message, std::ptrdiff_t start_pos)
208
162
{
209
162
   if(0 == this->m_pdata->m_status) // update the error code if not already set
210
162
      this->m_pdata->m_status = error_code;
211
162
   m_position = m_end; // don't bother parsing anything else
212
213
   //
214
   // Augment error message with the regular expression text:
215
   //
216
162
   if(start_pos == position)
217
162
      start_pos = (std::max)(static_cast<std::ptrdiff_t>(0), position - static_cast<std::ptrdiff_t>(10));
218
162
   std::ptrdiff_t end_pos = (std::min)(position + static_cast<std::ptrdiff_t>(10), static_cast<std::ptrdiff_t>(m_end - m_base));
219
162
   if(error_code != regex_constants::error_empty)
220
162
   {
221
162
      if((start_pos != 0) || (end_pos != (m_end - m_base)))
222
162
         message += "  The error occurred while parsing the regular expression fragment: '";
223
0
      else
224
0
         message += "  The error occurred while parsing the regular expression: '";
225
162
      if(start_pos != end_pos)
226
162
      {
227
162
         message += std::string(m_base + start_pos, m_base + position);
228
162
         message += ">>>HERE>>>";
229
162
         message += std::string(m_base + position, m_base + end_pos);
230
162
      }
231
162
      message += "'.";
232
162
   }
233
234
162
#ifndef BOOST_NO_EXCEPTIONS
235
162
   if(0 == (this->flags() & regex_constants::no_except))
236
162
   {
237
162
      boost::regex_error e(message, error_code, position);
238
162
      e.raise();
239
162
   }
240
#else
241
   (void)position; // suppress warnings.
242
#endif
243
162
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long)
Line
Count
Source
208
162
{
209
162
   if(0 == this->m_pdata->m_status) // update the error code if not already set
210
162
      this->m_pdata->m_status = error_code;
211
162
   m_position = m_end; // don't bother parsing anything else
212
213
   //
214
   // Augment error message with the regular expression text:
215
   //
216
162
   if(start_pos == position)
217
162
      start_pos = (std::max)(static_cast<std::ptrdiff_t>(0), position - static_cast<std::ptrdiff_t>(10));
218
162
   std::ptrdiff_t end_pos = (std::min)(position + static_cast<std::ptrdiff_t>(10), static_cast<std::ptrdiff_t>(m_end - m_base));
219
162
   if(error_code != regex_constants::error_empty)
220
162
   {
221
162
      if((start_pos != 0) || (end_pos != (m_end - m_base)))
222
162
         message += "  The error occurred while parsing the regular expression fragment: '";
223
0
      else
224
0
         message += "  The error occurred while parsing the regular expression: '";
225
162
      if(start_pos != end_pos)
226
162
      {
227
162
         message += std::string(m_base + start_pos, m_base + position);
228
162
         message += ">>>HERE>>>";
229
162
         message += std::string(m_base + position, m_base + end_pos);
230
162
      }
231
162
      message += "'.";
232
162
   }
233
234
162
#ifndef BOOST_NO_EXCEPTIONS
235
162
   if(0 == (this->flags() & regex_constants::no_except))
236
162
   {
237
162
      boost::regex_error e(message, error_code, position);
238
162
      e.raise();
239
162
   }
240
#else
241
   (void)position; // suppress warnings.
242
#endif
243
162
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::fail(boost::regex_constants::error_type, long, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, long)
244
245
template <class charT, class traits>
246
bool basic_regex_parser<charT, traits>::parse_all()
247
3.26M
{
248
3.26M
   if (++m_recursion_count > 400)
249
0
   {
250
      // exceeded internal limits
251
0
      fail(boost::regex_constants::error_complexity, m_position - m_base, "Exceeded nested brace limit.");
252
0
   }
253
3.26M
   bool result = true;
254
51.9M
   while(result && (m_position != m_end))
255
48.7M
   {
256
48.7M
      result = (this->*m_parser_proc)();
257
48.7M
   }
258
3.26M
   --m_recursion_count;
259
3.26M
   return result;
260
3.26M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_all()
Line
Count
Source
247
3.26M
{
248
3.26M
   if (++m_recursion_count > 400)
249
0
   {
250
      // exceeded internal limits
251
0
      fail(boost::regex_constants::error_complexity, m_position - m_base, "Exceeded nested brace limit.");
252
0
   }
253
3.26M
   bool result = true;
254
51.9M
   while(result && (m_position != m_end))
255
48.7M
   {
256
48.7M
      result = (this->*m_parser_proc)();
257
48.7M
   }
258
3.26M
   --m_recursion_count;
259
3.26M
   return result;
260
3.26M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_all()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_all()
261
262
#ifdef BOOST_REGEX_MSVC
263
#pragma warning(push)
264
#pragma warning(disable:4702)
265
#endif
266
template <class charT, class traits>
267
bool basic_regex_parser<charT, traits>::parse_basic()
268
0
{
269
0
   switch(this->m_traits.syntax_type(*m_position))
270
0
   {
271
0
   case regex_constants::syntax_escape:
272
0
      return parse_basic_escape();
273
0
   case regex_constants::syntax_dot:
274
0
      return parse_match_any();
275
0
   case regex_constants::syntax_caret:
276
0
      ++m_position;
277
0
      this->append_state(syntax_element_start_line);
278
0
      break;
279
0
   case regex_constants::syntax_dollar:
280
0
      ++m_position;
281
0
      this->append_state(syntax_element_end_line);
282
0
      break;
283
0
   case regex_constants::syntax_star:
284
0
      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))
285
0
         return parse_literal();
286
0
      else
287
0
      {
288
0
         ++m_position;
289
0
         return parse_repeat();
290
0
      }
291
0
   case regex_constants::syntax_plus:
292
0
      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
293
0
         return parse_literal();
294
0
      else
295
0
      {
296
0
         ++m_position;
297
0
         return parse_repeat(1);
298
0
      }
299
0
   case regex_constants::syntax_question:
300
0
      if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line) || !(this->flags() & regbase::emacs_ex))
301
0
         return parse_literal();
302
0
      else
303
0
      {
304
0
         ++m_position;
305
0
         return parse_repeat(0, 1);
306
0
      }
307
0
   case regex_constants::syntax_open_set:
308
0
      return parse_set();
309
0
   case regex_constants::syntax_newline:
310
0
      if(this->flags() & regbase::newline_alt)
311
0
         return parse_alt();
312
0
      else
313
0
         return parse_literal();
314
0
   default:
315
0
      return parse_literal();
316
0
   }
317
0
   return true;
318
0
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_basic()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_basic()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_basic()
319
320
#ifdef BOOST_REGEX_MSVC
321
#  pragma warning(push)
322
#if BOOST_REGEX_MSVC >= 1800
323
#pragma warning(disable:26812)
324
#endif
325
#endif
326
template <class charT, class traits>
327
bool basic_regex_parser<charT, traits>::parse_extended()
328
48.7M
{
329
48.7M
   bool result = true;
330
48.7M
   switch(this->m_traits.syntax_type(*m_position))
331
48.7M
   {
332
3.24M
   case regex_constants::syntax_open_mark:
333
3.24M
      return parse_open_paren();
334
3.22M
   case regex_constants::syntax_close_mark:
335
3.22M
      return false;
336
427k
   case regex_constants::syntax_escape:
337
427k
      return parse_extended_escape();
338
135k
   case regex_constants::syntax_dot:
339
135k
      return parse_match_any();
340
7.31k
   case regex_constants::syntax_caret:
341
7.31k
      ++m_position;
342
7.31k
      this->append_state(
343
7.31k
         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));
344
7.31k
      break;
345
15.3k
   case regex_constants::syntax_dollar:
346
15.3k
      ++m_position;
347
15.3k
      this->append_state(
348
15.3k
         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));
349
15.3k
      break;
350
110k
   case regex_constants::syntax_star:
351
110k
      if(m_position == this->m_base)
352
1
      {
353
1
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"*\" cannot start a regular expression.");
354
1
         return false;
355
1
      }
356
110k
      ++m_position;
357
110k
      return parse_repeat();
358
1.22M
   case regex_constants::syntax_question:
359
1.22M
      if(m_position == this->m_base)
360
0
      {
361
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"?\" cannot start a regular expression.");
362
0
         return false;
363
0
      }
364
1.22M
      ++m_position;
365
1.22M
      return parse_repeat(0,1);
366
134k
   case regex_constants::syntax_plus:
367
134k
      if(m_position == this->m_base)
368
0
      {
369
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"+\" cannot start a regular expression.");
370
0
         return false;
371
0
      }
372
134k
      ++m_position;
373
134k
      return parse_repeat(1);
374
19.2k
   case regex_constants::syntax_open_brace:
375
19.2k
      ++m_position;
376
19.2k
      return parse_repeat_range(false);
377
26.4k
   case regex_constants::syntax_close_brace:
378
26.4k
      if((this->flags() & regbase::no_perl_ex) == regbase::no_perl_ex)
379
0
      {
380
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
381
0
         return false;
382
0
      }
383
26.4k
      result = parse_literal();
384
26.4k
      break;
385
7.43M
   case regex_constants::syntax_or:
386
7.43M
      return parse_alt();
387
82.2k
   case regex_constants::syntax_open_set:
388
82.2k
      return parse_set();
389
77.4k
   case regex_constants::syntax_newline:
390
77.4k
      if(this->flags() & regbase::newline_alt)
391
0
         return parse_alt();
392
77.4k
      else
393
77.4k
         return parse_literal();
394
10.1k
   case regex_constants::syntax_hash:
395
      //
396
      // If we have a mod_x flag set, then skip until
397
      // we get to a newline character:
398
      //
399
10.1k
      if((this->flags() 
400
10.1k
         & (regbase::no_perl_ex|regbase::mod_x))
401
10.1k
         == regbase::mod_x)
402
96
      {
403
146k
         while((m_position != m_end) && !is_separator(*m_position++)){}
404
96
         return true;
405
96
      }
406
10.0k
      BOOST_REGEX_FALLTHROUGH;
407
32.5M
   default:
408
32.5M
      result = parse_literal();
409
32.5M
      break;
410
48.7M
   }
411
32.6M
   return result;
412
48.7M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_extended()
Line
Count
Source
328
48.7M
{
329
48.7M
   bool result = true;
330
48.7M
   switch(this->m_traits.syntax_type(*m_position))
331
48.7M
   {
332
3.24M
   case regex_constants::syntax_open_mark:
333
3.24M
      return parse_open_paren();
334
3.22M
   case regex_constants::syntax_close_mark:
335
3.22M
      return false;
336
427k
   case regex_constants::syntax_escape:
337
427k
      return parse_extended_escape();
338
135k
   case regex_constants::syntax_dot:
339
135k
      return parse_match_any();
340
7.31k
   case regex_constants::syntax_caret:
341
7.31k
      ++m_position;
342
7.31k
      this->append_state(
343
7.31k
         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));
344
7.31k
      break;
345
15.3k
   case regex_constants::syntax_dollar:
346
15.3k
      ++m_position;
347
15.3k
      this->append_state(
348
15.3k
         (this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));
349
15.3k
      break;
350
110k
   case regex_constants::syntax_star:
351
110k
      if(m_position == this->m_base)
352
1
      {
353
1
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"*\" cannot start a regular expression.");
354
1
         return false;
355
1
      }
356
110k
      ++m_position;
357
110k
      return parse_repeat();
358
1.22M
   case regex_constants::syntax_question:
359
1.22M
      if(m_position == this->m_base)
360
0
      {
361
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"?\" cannot start a regular expression.");
362
0
         return false;
363
0
      }
364
1.22M
      ++m_position;
365
1.22M
      return parse_repeat(0,1);
366
134k
   case regex_constants::syntax_plus:
367
134k
      if(m_position == this->m_base)
368
0
      {
369
0
         fail(regex_constants::error_badrepeat, 0, "The repeat operator \"+\" cannot start a regular expression.");
370
0
         return false;
371
0
      }
372
134k
      ++m_position;
373
134k
      return parse_repeat(1);
374
19.2k
   case regex_constants::syntax_open_brace:
375
19.2k
      ++m_position;
376
19.2k
      return parse_repeat_range(false);
377
26.4k
   case regex_constants::syntax_close_brace:
378
26.4k
      if((this->flags() & regbase::no_perl_ex) == regbase::no_perl_ex)
379
0
      {
380
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
381
0
         return false;
382
0
      }
383
26.4k
      result = parse_literal();
384
26.4k
      break;
385
7.43M
   case regex_constants::syntax_or:
386
7.43M
      return parse_alt();
387
82.2k
   case regex_constants::syntax_open_set:
388
82.2k
      return parse_set();
389
77.4k
   case regex_constants::syntax_newline:
390
77.4k
      if(this->flags() & regbase::newline_alt)
391
0
         return parse_alt();
392
77.4k
      else
393
77.4k
         return parse_literal();
394
10.1k
   case regex_constants::syntax_hash:
395
      //
396
      // If we have a mod_x flag set, then skip until
397
      // we get to a newline character:
398
      //
399
10.1k
      if((this->flags() 
400
10.1k
         & (regbase::no_perl_ex|regbase::mod_x))
401
10.1k
         == regbase::mod_x)
402
96
      {
403
146k
         while((m_position != m_end) && !is_separator(*m_position++)){}
404
96
         return true;
405
96
      }
406
10.0k
      BOOST_REGEX_FALLTHROUGH;
407
32.5M
   default:
408
32.5M
      result = parse_literal();
409
32.5M
      break;
410
48.7M
   }
411
32.6M
   return result;
412
48.7M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_extended()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_extended()
413
#ifdef BOOST_REGEX_MSVC
414
#  pragma warning(pop)
415
#endif
416
#ifdef BOOST_REGEX_MSVC
417
#pragma warning(pop)
418
#endif
419
420
template <class charT, class traits>
421
bool basic_regex_parser<charT, traits>::parse_literal()
422
32.6M
{
423
   // append this as a literal provided it's not a space character
424
   // or the perl option regbase::mod_x is not set:
425
32.6M
   if(
426
32.6M
      ((this->flags() 
427
32.6M
         & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex)) 
428
32.6M
            != regbase::mod_x)
429
32.6M
      || !this->m_traits.isctype(*m_position, this->m_mask_space))
430
32.6M
         this->append_literal(*m_position);
431
32.6M
   ++m_position;
432
32.6M
   return true;
433
32.6M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_literal()
Line
Count
Source
422
32.6M
{
423
   // append this as a literal provided it's not a space character
424
   // or the perl option regbase::mod_x is not set:
425
32.6M
   if(
426
32.6M
      ((this->flags() 
427
32.6M
         & (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex)) 
428
32.6M
            != regbase::mod_x)
429
32.6M
      || !this->m_traits.isctype(*m_position, this->m_mask_space))
430
32.6M
         this->append_literal(*m_position);
431
32.6M
   ++m_position;
432
32.6M
   return true;
433
32.6M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_literal()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_literal()
434
435
template <class charT, class traits>
436
bool basic_regex_parser<charT, traits>::parse_open_paren()
437
3.24M
{
438
   //
439
   // skip the '(' and error check:
440
   //
441
3.24M
   if(++m_position == m_end)
442
4
   {
443
4
      fail(regex_constants::error_paren, m_position - m_base);
444
4
      return false;
445
4
   }
446
   //
447
   // begin by checking for a perl-style (?...) extension:
448
   //
449
3.24M
   if(
450
3.24M
         ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
451
3.24M
         || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
452
3.24M
     )
453
3.24M
   {
454
3.24M
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
455
157k
         return parse_perl_extension();
456
3.08M
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_star)
457
21.2k
         return parse_perl_verb();
458
3.08M
   }
459
   //
460
   // update our mark count, and append the required state:
461
   //
462
3.06M
   unsigned markid = 0;
463
3.06M
   if(0 == (this->flags() & regbase::nosubs))
464
3.06M
   {
465
3.06M
      markid = ++m_mark_count;
466
3.06M
      if(this->flags() & regbase::save_subexpression_location)
467
0
         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));
468
3.06M
   }
469
3.06M
   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
470
3.06M
   pb->index = markid;
471
3.06M
   pb->icase = this->flags() & regbase::icase;
472
3.06M
   std::ptrdiff_t last_paren_start = this->getoffset(pb);
473
   // back up insertion point for alternations, and set new point:
474
3.06M
   std::ptrdiff_t last_alt_point = m_alt_insert_point;
475
3.06M
   this->m_pdata->m_data.align();
476
3.06M
   m_alt_insert_point = this->m_pdata->m_data.size();
477
   //
478
   // back up the current flags in case we have a nested (?imsx) group:
479
   //
480
3.06M
   regex_constants::syntax_option_type opts = this->flags();
481
3.06M
   bool old_case_change = m_has_case_change;
482
3.06M
   m_has_case_change = false; // no changes to this scope as yet...
483
   //
484
   // Back up branch reset data in case we have a nested (?|...)
485
   //
486
3.06M
   int mark_reset = m_mark_reset;
487
3.06M
   m_mark_reset = -1;
488
   //
489
   // now recursively add more states, this will terminate when we get to a
490
   // matching ')' :
491
   //
492
3.06M
   parse_all();
493
   //
494
   // Unwind pushed alternatives:
495
   //
496
3.06M
   if(0 == unwind_alts(last_paren_start))
497
0
      return false;
498
   //
499
   // restore flags:
500
   //
501
3.06M
   if(m_has_case_change)
502
13.7k
   {
503
      // the case has changed in one or more of the alternatives
504
      // within the scoped (...) block: we have to add a state
505
      // to reset the case sensitivity:
506
13.7k
      static_cast<re_case*>(
507
13.7k
         this->append_state(syntax_element_toggle_case, sizeof(re_case))
508
13.7k
         )->icase = opts & regbase::icase;
509
13.7k
   }
510
3.06M
   this->flags(opts);
511
3.06M
   m_has_case_change = old_case_change;
512
   //
513
   // restore branch reset:
514
   //
515
3.06M
   m_mark_reset = mark_reset;
516
   //
517
   // we either have a ')' or we have run out of characters prematurely:
518
   //
519
3.06M
   if(m_position == m_end)
520
27
   {
521
27
      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
522
27
      return false;
523
27
   }
524
3.06M
   if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
525
0
      return false;
526
3.06M
   if(markid && (this->flags() & regbase::save_subexpression_location))
527
0
      this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);
528
3.06M
   ++m_position;
529
   //
530
   // append closing parenthesis state:
531
   //
532
3.06M
   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
533
3.06M
   pb->index = markid;
534
3.06M
   pb->icase = this->flags() & regbase::icase;
535
3.06M
   this->m_paren_start = last_paren_start;
536
   //
537
   // restore the alternate insertion point:
538
   //
539
3.06M
   this->m_alt_insert_point = last_alt_point;
540
541
3.06M
   return true;
542
3.06M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_open_paren()
Line
Count
Source
437
3.24M
{
438
   //
439
   // skip the '(' and error check:
440
   //
441
3.24M
   if(++m_position == m_end)
442
4
   {
443
4
      fail(regex_constants::error_paren, m_position - m_base);
444
4
      return false;
445
4
   }
446
   //
447
   // begin by checking for a perl-style (?...) extension:
448
   //
449
3.24M
   if(
450
3.24M
         ((this->flags() & (regbase::main_option_type | regbase::no_perl_ex)) == 0)
451
3.24M
         || ((this->flags() & (regbase::main_option_type | regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
452
3.24M
     )
453
3.24M
   {
454
3.24M
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
455
157k
         return parse_perl_extension();
456
3.08M
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_star)
457
21.2k
         return parse_perl_verb();
458
3.08M
   }
459
   //
460
   // update our mark count, and append the required state:
461
   //
462
3.06M
   unsigned markid = 0;
463
3.06M
   if(0 == (this->flags() & regbase::nosubs))
464
3.06M
   {
465
3.06M
      markid = ++m_mark_count;
466
3.06M
      if(this->flags() & regbase::save_subexpression_location)
467
0
         this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 1, 0));
468
3.06M
   }
469
3.06M
   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
470
3.06M
   pb->index = markid;
471
3.06M
   pb->icase = this->flags() & regbase::icase;
472
3.06M
   std::ptrdiff_t last_paren_start = this->getoffset(pb);
473
   // back up insertion point for alternations, and set new point:
474
3.06M
   std::ptrdiff_t last_alt_point = m_alt_insert_point;
475
3.06M
   this->m_pdata->m_data.align();
476
3.06M
   m_alt_insert_point = this->m_pdata->m_data.size();
477
   //
478
   // back up the current flags in case we have a nested (?imsx) group:
479
   //
480
3.06M
   regex_constants::syntax_option_type opts = this->flags();
481
3.06M
   bool old_case_change = m_has_case_change;
482
3.06M
   m_has_case_change = false; // no changes to this scope as yet...
483
   //
484
   // Back up branch reset data in case we have a nested (?|...)
485
   //
486
3.06M
   int mark_reset = m_mark_reset;
487
3.06M
   m_mark_reset = -1;
488
   //
489
   // now recursively add more states, this will terminate when we get to a
490
   // matching ')' :
491
   //
492
3.06M
   parse_all();
493
   //
494
   // Unwind pushed alternatives:
495
   //
496
3.06M
   if(0 == unwind_alts(last_paren_start))
497
0
      return false;
498
   //
499
   // restore flags:
500
   //
501
3.06M
   if(m_has_case_change)
502
13.7k
   {
503
      // the case has changed in one or more of the alternatives
504
      // within the scoped (...) block: we have to add a state
505
      // to reset the case sensitivity:
506
13.7k
      static_cast<re_case*>(
507
13.7k
         this->append_state(syntax_element_toggle_case, sizeof(re_case))
508
13.7k
         )->icase = opts & regbase::icase;
509
13.7k
   }
510
3.06M
   this->flags(opts);
511
3.06M
   m_has_case_change = old_case_change;
512
   //
513
   // restore branch reset:
514
   //
515
3.06M
   m_mark_reset = mark_reset;
516
   //
517
   // we either have a ')' or we have run out of characters prematurely:
518
   //
519
3.06M
   if(m_position == m_end)
520
27
   {
521
27
      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
522
27
      return false;
523
27
   }
524
3.06M
   if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
525
0
      return false;
526
3.06M
   if(markid && (this->flags() & regbase::save_subexpression_location))
527
0
      this->m_pdata->m_subs.at(markid - 1).second = std::distance(m_base, m_position);
528
3.06M
   ++m_position;
529
   //
530
   // append closing parenthesis state:
531
   //
532
3.06M
   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
533
3.06M
   pb->index = markid;
534
3.06M
   pb->icase = this->flags() & regbase::icase;
535
3.06M
   this->m_paren_start = last_paren_start;
536
   //
537
   // restore the alternate insertion point:
538
   //
539
3.06M
   this->m_alt_insert_point = last_alt_point;
540
541
3.06M
   return true;
542
3.06M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_open_paren()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_open_paren()
543
544
template <class charT, class traits>
545
bool basic_regex_parser<charT, traits>::parse_basic_escape()
546
0
{
547
0
   if(++m_position == m_end)
548
0
   {
549
0
      fail(regex_constants::error_paren, m_position - m_base);
550
0
      return false;
551
0
   }
552
0
   bool result = true;
553
0
   switch(this->m_traits.escape_syntax_type(*m_position))
554
0
   {
555
0
   case regex_constants::syntax_open_mark:
556
0
      return parse_open_paren();
557
0
   case regex_constants::syntax_close_mark:
558
0
      return false;
559
0
   case regex_constants::syntax_plus:
560
0
      if(this->flags() & regex_constants::bk_plus_qm)
561
0
      {
562
0
         ++m_position;
563
0
         return parse_repeat(1);
564
0
      }
565
0
      else
566
0
         return parse_literal();
567
0
   case regex_constants::syntax_question:
568
0
      if(this->flags() & regex_constants::bk_plus_qm)
569
0
      {
570
0
         ++m_position;
571
0
         return parse_repeat(0, 1);
572
0
      }
573
0
      else
574
0
         return parse_literal();
575
0
   case regex_constants::syntax_open_brace:
576
0
      if(this->flags() & regbase::no_intervals)
577
0
         return parse_literal();
578
0
      ++m_position;
579
0
      return parse_repeat_range(true);
580
0
   case regex_constants::syntax_close_brace:
581
0
      if(this->flags() & regbase::no_intervals)
582
0
         return parse_literal();
583
0
      fail(regex_constants::error_brace, this->m_position - this->m_base, "Found a closing repetition operator } with no corresponding {.");
584
0
      return false;
585
0
   case regex_constants::syntax_or:
586
0
      if(this->flags() & regbase::bk_vbar)
587
0
         return parse_alt();
588
0
      else
589
0
         result = parse_literal();
590
0
      break;
591
0
   case regex_constants::syntax_digit:
592
0
      return parse_backref();
593
0
   case regex_constants::escape_type_start_buffer:
594
0
      if(this->flags() & regbase::emacs_ex)
595
0
      {
596
0
         ++m_position;
597
0
         this->append_state(syntax_element_buffer_start);
598
0
      }
599
0
      else
600
0
         result = parse_literal();
601
0
      break;
602
0
   case regex_constants::escape_type_end_buffer:
603
0
      if(this->flags() & regbase::emacs_ex)
604
0
      {
605
0
         ++m_position;
606
0
         this->append_state(syntax_element_buffer_end);
607
0
      }
608
0
      else
609
0
         result = parse_literal();
610
0
      break;
611
0
   case regex_constants::escape_type_word_assert:
612
0
      if(this->flags() & regbase::emacs_ex)
613
0
      {
614
0
         ++m_position;
615
0
         this->append_state(syntax_element_word_boundary);
616
0
      }
617
0
      else
618
0
         result = parse_literal();
619
0
      break;
620
0
   case regex_constants::escape_type_not_word_assert:
621
0
      if(this->flags() & regbase::emacs_ex)
622
0
      {
623
0
         ++m_position;
624
0
         this->append_state(syntax_element_within_word);
625
0
      }
626
0
      else
627
0
         result = parse_literal();
628
0
      break;
629
0
   case regex_constants::escape_type_left_word:
630
0
      if(this->flags() & regbase::emacs_ex)
631
0
      {
632
0
         ++m_position;
633
0
         this->append_state(syntax_element_word_start);
634
0
      }
635
0
      else
636
0
         result = parse_literal();
637
0
      break;
638
0
   case regex_constants::escape_type_right_word:
639
0
      if(this->flags() & regbase::emacs_ex)
640
0
      {
641
0
         ++m_position;
642
0
         this->append_state(syntax_element_word_end);
643
0
      }
644
0
      else
645
0
         result = parse_literal();
646
0
      break;
647
0
   default:
648
0
      if(this->flags() & regbase::emacs_ex)
649
0
      {
650
0
         bool negate = true;
651
0
         switch(*m_position)
652
0
         {
653
0
         case 'w':
654
0
            negate = false;
655
0
            BOOST_REGEX_FALLTHROUGH;
656
0
         case 'W':
657
0
            {
658
0
            basic_char_set<charT, traits> char_set;
659
0
            if(negate)
660
0
               char_set.negate();
661
0
            char_set.add_class(this->m_word_mask);
662
0
            if(0 == this->append_set(char_set))
663
0
            {
664
0
               fail(regex_constants::error_ctype, m_position - m_base);
665
0
               return false;
666
0
            }
667
0
            ++m_position;
668
0
            return true;
669
0
            }
670
0
         case 's':
671
0
            negate = false;
672
0
            BOOST_REGEX_FALLTHROUGH;
673
0
         case 'S':
674
0
            return add_emacs_code(negate);
675
0
         case 'c':
676
0
         case 'C':
677
            // not supported yet:
678
0
            fail(regex_constants::error_escape, m_position - m_base, "The \\c and \\C escape sequences are not supported by POSIX basic regular expressions: try the Perl syntax instead.");
679
0
            return false;
680
0
         default:
681
0
            break;
682
0
         }
683
0
      }
684
0
      result = parse_literal();
685
0
      break;
686
0
   }
687
0
   return result;
688
0
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_basic_escape()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_basic_escape()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_basic_escape()
689
690
template <class charT, class traits>
691
bool basic_regex_parser<charT, traits>::parse_extended_escape()
692
427k
{
693
427k
   ++m_position;
694
427k
   if(m_position == m_end)
695
2
   {
696
2
      fail(regex_constants::error_escape, m_position - m_base, "Incomplete escape sequence found.");
697
2
      return false;
698
2
   }
699
427k
   bool negate = false; // in case this is a character class escape: \w \d etc
700
427k
   switch(this->m_traits.escape_syntax_type(*m_position))
701
427k
   {
702
2.88k
   case regex_constants::escape_type_not_class:
703
2.88k
      negate = true;
704
2.88k
      BOOST_REGEX_FALLTHROUGH;
705
226k
   case regex_constants::escape_type_class:
706
226k
      {
707
226k
escape_type_class_jump:
708
226k
         typedef typename traits::char_class_type m_type;
709
226k
         m_type m = this->m_traits.lookup_classname(m_position, m_position+1);
710
226k
         if(m != 0)
711
226k
         {
712
226k
            basic_char_set<charT, traits> char_set;
713
226k
            if(negate)
714
2.78k
               char_set.negate();
715
226k
            char_set.add_class(m);
716
226k
            if(0 == this->append_set(char_set))
717
0
            {
718
0
               fail(regex_constants::error_ctype, m_position - m_base);
719
0
               return false;
720
0
            }
721
226k
            ++m_position;
722
226k
            return true;
723
226k
         }
724
         //
725
         // not a class, just a regular unknown escape:
726
         //
727
123
         this->append_literal(unescape_character());
728
123
         break;
729
226k
      }
730
68.6k
   case regex_constants::syntax_digit:
731
68.6k
      return parse_backref();
732
3.42k
   case regex_constants::escape_type_left_word:
733
3.42k
      ++m_position;
734
3.42k
      this->append_state(syntax_element_word_start);
735
3.42k
      break;
736
6.68k
   case regex_constants::escape_type_right_word:
737
6.68k
      ++m_position;
738
6.68k
      this->append_state(syntax_element_word_end);
739
6.68k
      break;
740
33.0k
   case regex_constants::escape_type_start_buffer:
741
33.0k
      ++m_position;
742
33.0k
      this->append_state(syntax_element_buffer_start);
743
33.0k
      break;
744
710
   case regex_constants::escape_type_end_buffer:
745
710
      ++m_position;
746
710
      this->append_state(syntax_element_buffer_end);
747
710
      break;
748
195
   case regex_constants::escape_type_word_assert:
749
195
      ++m_position;
750
195
      this->append_state(syntax_element_word_boundary);
751
195
      break;
752
17
   case regex_constants::escape_type_not_word_assert:
753
17
      ++m_position;
754
17
      this->append_state(syntax_element_within_word);
755
17
      break;
756
91
   case regex_constants::escape_type_Z:
757
91
      ++m_position;
758
91
      this->append_state(syntax_element_soft_buffer_end);
759
91
      break;
760
9.55k
   case regex_constants::escape_type_Q:
761
9.55k
      return parse_QE();
762
85
   case regex_constants::escape_type_C:
763
85
      return parse_match_any();
764
390
   case regex_constants::escape_type_X:
765
390
      ++m_position;
766
390
      this->append_state(syntax_element_combining);
767
390
      break;
768
18.4k
   case regex_constants::escape_type_G:
769
18.4k
      ++m_position;
770
18.4k
      this->append_state(syntax_element_restart_continue);
771
18.4k
      break;
772
43
   case regex_constants::escape_type_not_property:
773
43
      negate = true;
774
43
      BOOST_REGEX_FALLTHROUGH;
775
44
   case regex_constants::escape_type_property:
776
44
      {
777
44
         ++m_position;
778
44
         char_class_type m;
779
44
         if(m_position == m_end)
780
0
         {
781
0
            fail(regex_constants::error_escape, m_position - m_base, "Incomplete property escape found.");
782
0
            return false;
783
0
         }
784
         // maybe have \p{ddd}
785
44
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
786
35
         {
787
35
            const charT* base = m_position;
788
            // skip forward until we find enclosing brace:
789
126k
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
790
126k
               ++m_position;
791
35
            if(m_position == m_end)
792
0
            {
793
0
               fail(regex_constants::error_escape, m_position - m_base, "Closing } missing from property escape sequence.");
794
0
               return false;
795
0
            }
796
35
            m = this->m_traits.lookup_classname(++base, m_position++);
797
35
         }
798
9
         else
799
9
         {
800
9
            m = this->m_traits.lookup_classname(m_position, m_position+1);
801
9
            ++m_position;
802
9
         }
803
44
         if(m != 0)
804
42
         {
805
42
            basic_char_set<charT, traits> char_set;
806
42
            if(negate)
807
42
               char_set.negate();
808
42
            char_set.add_class(m);
809
42
            if(0 == this->append_set(char_set))
810
0
            {
811
0
               fail(regex_constants::error_ctype, m_position - m_base);
812
0
               return false;
813
0
            }
814
42
            return true;
815
42
         }
816
2
         fail(regex_constants::error_ctype, m_position - m_base, "Escape sequence was neither a valid property nor a valid character class name.");
817
2
         return false;
818
44
      }
819
12
   case regex_constants::escape_type_reset_start_mark:
820
12
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
821
12
      {
822
12
         re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
823
12
         pb->index = -5;
824
12
         pb->icase = this->flags() & regbase::icase;
825
12
         this->m_pdata->m_data.align();
826
12
         ++m_position;
827
12
         return true;
828
12
      }
829
0
      goto escape_type_class_jump;
830
785
   case regex_constants::escape_type_line_ending:
831
785
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
832
785
      {
833
785
         const charT* e = get_escape_R_string<charT>();
834
785
         const charT* old_position = m_position;
835
785
         const charT* old_end = m_end;
836
785
         const charT* old_base = m_base;
837
785
         m_position = e;
838
785
         m_base = e;
839
785
         m_end = e + traits::length(e);
840
785
         bool r = parse_all();
841
785
         m_position = ++old_position;
842
785
         m_end = old_end;
843
785
         m_base = old_base;
844
785
         return r;
845
785
      }
846
0
      goto escape_type_class_jump;
847
215
   case regex_constants::escape_type_extended_backref:
848
215
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
849
215
      {
850
215
         bool have_brace = false;
851
215
         bool negative = false;
852
215
         static const char incomplete_message[] = "Incomplete \\g escape found.";
853
215
         if(++m_position == m_end)
854
0
         {
855
0
            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
856
0
            return false;
857
0
         }
858
         // maybe have \g{ddd}
859
215
         regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position);
860
215
         regex_constants::syntax_type syn_end = 0;
861
215
         if((syn == regex_constants::syntax_open_brace) 
862
215
            || (syn == regex_constants::escape_type_left_word)
863
215
            || (syn == regex_constants::escape_type_end_buffer))
864
132
         {
865
132
            if(++m_position == m_end)
866
0
            {
867
0
               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
868
0
               return false;
869
0
            }
870
132
            have_brace = true;
871
132
            switch(syn)
872
132
            {
873
0
            case regex_constants::syntax_open_brace:
874
0
               syn_end = regex_constants::syntax_close_brace;
875
0
               break;
876
3
            case regex_constants::escape_type_left_word:
877
3
               syn_end = regex_constants::escape_type_right_word;
878
3
               break;
879
129
            default:
880
129
               syn_end = regex_constants::escape_type_end_buffer;
881
129
               break;
882
132
            }
883
132
         }
884
215
         negative = (*m_position == static_cast<charT>('-'));
885
215
         if((negative) && (++m_position == m_end))
886
0
         {
887
0
            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
888
0
            return false;
889
0
         }
890
215
         const charT* pc = m_position;
891
215
         std::intmax_t i = this->m_traits.toi(pc, m_end, 10);
892
215
         if((i < 0) && syn_end)
893
129
         {
894
            // Check for a named capture, get the leftmost one if there is more than one:
895
129
            const charT* base = m_position;
896
141
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end))
897
12
            {
898
12
               ++m_position;
899
12
            }
900
129
            i = hash_value_from_capture_name(base, m_position);
901
129
            pc = m_position;
902
129
         }
903
215
         if(negative)
904
44
            i = 1 + (static_cast<std::intmax_t>(m_mark_count) - i);
905
215
         if(((i < hash_value_mask) && (i > 0)) || ((i >= hash_value_mask) && (this->m_pdata->get_id((int)i) > 0)))
906
212
         {
907
212
            m_position = pc;
908
212
            re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
909
212
            pb->index = (int)i;
910
212
            pb->icase = this->flags() & regbase::icase;
911
212
            if ((i > m_max_backref) && (i < hash_value_mask))
912
44
               m_max_backref = i;
913
212
         }
914
3
         else
915
3
         {
916
3
            fail(regex_constants::error_backref, m_position - m_base);
917
3
            return false;
918
3
         }
919
212
         m_position = pc;
920
212
         if(have_brace)
921
130
         {
922
130
            if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end))
923
0
            {
924
0
               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
925
0
               return false;
926
0
            }
927
130
            ++m_position;
928
130
         }
929
212
         return true;
930
212
      }
931
0
      goto escape_type_class_jump;
932
14
   case regex_constants::escape_type_control_v:
933
14
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
934
14
         goto escape_type_class_jump;
935
0
      BOOST_REGEX_FALLTHROUGH;
936
57.9k
   default:
937
57.9k
      this->append_literal(unescape_character());
938
57.9k
      break;
939
427k
   }
940
121k
   return true;
941
427k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_extended_escape()
Line
Count
Source
692
427k
{
693
427k
   ++m_position;
694
427k
   if(m_position == m_end)
695
2
   {
696
2
      fail(regex_constants::error_escape, m_position - m_base, "Incomplete escape sequence found.");
697
2
      return false;
698
2
   }
699
427k
   bool negate = false; // in case this is a character class escape: \w \d etc
700
427k
   switch(this->m_traits.escape_syntax_type(*m_position))
701
427k
   {
702
2.88k
   case regex_constants::escape_type_not_class:
703
2.88k
      negate = true;
704
2.88k
      BOOST_REGEX_FALLTHROUGH;
705
226k
   case regex_constants::escape_type_class:
706
226k
      {
707
226k
escape_type_class_jump:
708
226k
         typedef typename traits::char_class_type m_type;
709
226k
         m_type m = this->m_traits.lookup_classname(m_position, m_position+1);
710
226k
         if(m != 0)
711
226k
         {
712
226k
            basic_char_set<charT, traits> char_set;
713
226k
            if(negate)
714
2.78k
               char_set.negate();
715
226k
            char_set.add_class(m);
716
226k
            if(0 == this->append_set(char_set))
717
0
            {
718
0
               fail(regex_constants::error_ctype, m_position - m_base);
719
0
               return false;
720
0
            }
721
226k
            ++m_position;
722
226k
            return true;
723
226k
         }
724
         //
725
         // not a class, just a regular unknown escape:
726
         //
727
123
         this->append_literal(unescape_character());
728
123
         break;
729
226k
      }
730
68.6k
   case regex_constants::syntax_digit:
731
68.6k
      return parse_backref();
732
3.42k
   case regex_constants::escape_type_left_word:
733
3.42k
      ++m_position;
734
3.42k
      this->append_state(syntax_element_word_start);
735
3.42k
      break;
736
6.68k
   case regex_constants::escape_type_right_word:
737
6.68k
      ++m_position;
738
6.68k
      this->append_state(syntax_element_word_end);
739
6.68k
      break;
740
33.0k
   case regex_constants::escape_type_start_buffer:
741
33.0k
      ++m_position;
742
33.0k
      this->append_state(syntax_element_buffer_start);
743
33.0k
      break;
744
710
   case regex_constants::escape_type_end_buffer:
745
710
      ++m_position;
746
710
      this->append_state(syntax_element_buffer_end);
747
710
      break;
748
195
   case regex_constants::escape_type_word_assert:
749
195
      ++m_position;
750
195
      this->append_state(syntax_element_word_boundary);
751
195
      break;
752
17
   case regex_constants::escape_type_not_word_assert:
753
17
      ++m_position;
754
17
      this->append_state(syntax_element_within_word);
755
17
      break;
756
91
   case regex_constants::escape_type_Z:
757
91
      ++m_position;
758
91
      this->append_state(syntax_element_soft_buffer_end);
759
91
      break;
760
9.55k
   case regex_constants::escape_type_Q:
761
9.55k
      return parse_QE();
762
85
   case regex_constants::escape_type_C:
763
85
      return parse_match_any();
764
390
   case regex_constants::escape_type_X:
765
390
      ++m_position;
766
390
      this->append_state(syntax_element_combining);
767
390
      break;
768
18.4k
   case regex_constants::escape_type_G:
769
18.4k
      ++m_position;
770
18.4k
      this->append_state(syntax_element_restart_continue);
771
18.4k
      break;
772
43
   case regex_constants::escape_type_not_property:
773
43
      negate = true;
774
43
      BOOST_REGEX_FALLTHROUGH;
775
44
   case regex_constants::escape_type_property:
776
44
      {
777
44
         ++m_position;
778
44
         char_class_type m;
779
44
         if(m_position == m_end)
780
0
         {
781
0
            fail(regex_constants::error_escape, m_position - m_base, "Incomplete property escape found.");
782
0
            return false;
783
0
         }
784
         // maybe have \p{ddd}
785
44
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
786
35
         {
787
35
            const charT* base = m_position;
788
            // skip forward until we find enclosing brace:
789
126k
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
790
126k
               ++m_position;
791
35
            if(m_position == m_end)
792
0
            {
793
0
               fail(regex_constants::error_escape, m_position - m_base, "Closing } missing from property escape sequence.");
794
0
               return false;
795
0
            }
796
35
            m = this->m_traits.lookup_classname(++base, m_position++);
797
35
         }
798
9
         else
799
9
         {
800
9
            m = this->m_traits.lookup_classname(m_position, m_position+1);
801
9
            ++m_position;
802
9
         }
803
44
         if(m != 0)
804
42
         {
805
42
            basic_char_set<charT, traits> char_set;
806
42
            if(negate)
807
42
               char_set.negate();
808
42
            char_set.add_class(m);
809
42
            if(0 == this->append_set(char_set))
810
0
            {
811
0
               fail(regex_constants::error_ctype, m_position - m_base);
812
0
               return false;
813
0
            }
814
42
            return true;
815
42
         }
816
2
         fail(regex_constants::error_ctype, m_position - m_base, "Escape sequence was neither a valid property nor a valid character class name.");
817
2
         return false;
818
44
      }
819
12
   case regex_constants::escape_type_reset_start_mark:
820
12
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
821
12
      {
822
12
         re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
823
12
         pb->index = -5;
824
12
         pb->icase = this->flags() & regbase::icase;
825
12
         this->m_pdata->m_data.align();
826
12
         ++m_position;
827
12
         return true;
828
12
      }
829
0
      goto escape_type_class_jump;
830
785
   case regex_constants::escape_type_line_ending:
831
785
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
832
785
      {
833
785
         const charT* e = get_escape_R_string<charT>();
834
785
         const charT* old_position = m_position;
835
785
         const charT* old_end = m_end;
836
785
         const charT* old_base = m_base;
837
785
         m_position = e;
838
785
         m_base = e;
839
785
         m_end = e + traits::length(e);
840
785
         bool r = parse_all();
841
785
         m_position = ++old_position;
842
785
         m_end = old_end;
843
785
         m_base = old_base;
844
785
         return r;
845
785
      }
846
0
      goto escape_type_class_jump;
847
215
   case regex_constants::escape_type_extended_backref:
848
215
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
849
215
      {
850
215
         bool have_brace = false;
851
215
         bool negative = false;
852
215
         static const char incomplete_message[] = "Incomplete \\g escape found.";
853
215
         if(++m_position == m_end)
854
0
         {
855
0
            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
856
0
            return false;
857
0
         }
858
         // maybe have \g{ddd}
859
215
         regex_constants::syntax_type syn = this->m_traits.syntax_type(*m_position);
860
215
         regex_constants::syntax_type syn_end = 0;
861
215
         if((syn == regex_constants::syntax_open_brace) 
862
215
            || (syn == regex_constants::escape_type_left_word)
863
215
            || (syn == regex_constants::escape_type_end_buffer))
864
132
         {
865
132
            if(++m_position == m_end)
866
0
            {
867
0
               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
868
0
               return false;
869
0
            }
870
132
            have_brace = true;
871
132
            switch(syn)
872
132
            {
873
0
            case regex_constants::syntax_open_brace:
874
0
               syn_end = regex_constants::syntax_close_brace;
875
0
               break;
876
3
            case regex_constants::escape_type_left_word:
877
3
               syn_end = regex_constants::escape_type_right_word;
878
3
               break;
879
129
            default:
880
129
               syn_end = regex_constants::escape_type_end_buffer;
881
129
               break;
882
132
            }
883
132
         }
884
215
         negative = (*m_position == static_cast<charT>('-'));
885
215
         if((negative) && (++m_position == m_end))
886
0
         {
887
0
            fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
888
0
            return false;
889
0
         }
890
215
         const charT* pc = m_position;
891
215
         std::intmax_t i = this->m_traits.toi(pc, m_end, 10);
892
215
         if((i < 0) && syn_end)
893
129
         {
894
            // Check for a named capture, get the leftmost one if there is more than one:
895
129
            const charT* base = m_position;
896
141
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != syn_end))
897
12
            {
898
12
               ++m_position;
899
12
            }
900
129
            i = hash_value_from_capture_name(base, m_position);
901
129
            pc = m_position;
902
129
         }
903
215
         if(negative)
904
44
            i = 1 + (static_cast<std::intmax_t>(m_mark_count) - i);
905
215
         if(((i < hash_value_mask) && (i > 0)) || ((i >= hash_value_mask) && (this->m_pdata->get_id((int)i) > 0)))
906
212
         {
907
212
            m_position = pc;
908
212
            re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
909
212
            pb->index = (int)i;
910
212
            pb->icase = this->flags() & regbase::icase;
911
212
            if ((i > m_max_backref) && (i < hash_value_mask))
912
44
               m_max_backref = i;
913
212
         }
914
3
         else
915
3
         {
916
3
            fail(regex_constants::error_backref, m_position - m_base);
917
3
            return false;
918
3
         }
919
212
         m_position = pc;
920
212
         if(have_brace)
921
130
         {
922
130
            if((m_position == m_end) || (this->m_traits.syntax_type(*m_position) != syn_end))
923
0
            {
924
0
               fail(regex_constants::error_escape, m_position - m_base, incomplete_message);
925
0
               return false;
926
0
            }
927
130
            ++m_position;
928
130
         }
929
212
         return true;
930
212
      }
931
0
      goto escape_type_class_jump;
932
14
   case regex_constants::escape_type_control_v:
933
14
      if(0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
934
14
         goto escape_type_class_jump;
935
0
      BOOST_REGEX_FALLTHROUGH;
936
57.9k
   default:
937
57.9k
      this->append_literal(unescape_character());
938
57.9k
      break;
939
427k
   }
940
121k
   return true;
941
427k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_extended_escape()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_extended_escape()
942
943
template <class charT, class traits>
944
bool basic_regex_parser<charT, traits>::parse_match_any()
945
135k
{
946
   //
947
   // we have a '.' that can match any character:
948
   //
949
135k
   ++m_position;
950
135k
   static_cast<re_dot*>(
951
135k
      this->append_state(syntax_element_wild, sizeof(re_dot))
952
135k
      )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s 
953
135k
      ? BOOST_REGEX_DETAIL_NS::force_not_newline 
954
135k
         : this->flags() & regbase::mod_s ?
955
133k
            BOOST_REGEX_DETAIL_NS::force_newline : BOOST_REGEX_DETAIL_NS::dont_care);
956
135k
   return true;
957
135k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_match_any()
Line
Count
Source
945
135k
{
946
   //
947
   // we have a '.' that can match any character:
948
   //
949
135k
   ++m_position;
950
135k
   static_cast<re_dot*>(
951
135k
      this->append_state(syntax_element_wild, sizeof(re_dot))
952
135k
      )->mask = static_cast<unsigned char>(this->flags() & regbase::no_mod_s 
953
135k
      ? BOOST_REGEX_DETAIL_NS::force_not_newline 
954
135k
         : this->flags() & regbase::mod_s ?
955
133k
            BOOST_REGEX_DETAIL_NS::force_newline : BOOST_REGEX_DETAIL_NS::dont_care);
956
135k
   return true;
957
135k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_match_any()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_match_any()
958
959
template <class charT, class traits>
960
bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)
961
1.47M
{
962
1.47M
   bool greedy = true;
963
1.47M
   bool possessive = false;
964
1.47M
   std::size_t insert_point;
965
   // 
966
   // when we get to here we may have a non-greedy ? mark still to come:
967
   //
968
1.47M
   if((m_position != m_end) 
969
1.47M
      && (
970
1.47M
            (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
971
1.47M
            || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))
972
1.47M
         )
973
1.47M
      )
974
1.47M
   {
975
      // OK we have a perl or emacs regex, check for a '?':
976
1.47M
      if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
977
6.02k
      {
978
         // whitespace skip:
979
6.18k
         while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
980
166
            ++m_position;
981
6.02k
      }
982
1.47M
      if((m_position != m_end) && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question))
983
35.4k
      {
984
35.4k
         greedy = false;
985
35.4k
         ++m_position;
986
35.4k
      }
987
      // for perl regexes only check for possessive ++ repeats.
988
1.47M
      if((m_position != m_end)
989
1.47M
         && (0 == (this->flags() & regbase::main_option_type)) 
990
1.47M
         && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))
991
6.07k
      {
992
6.07k
         possessive = true;
993
6.07k
         ++m_position;
994
6.07k
      }
995
1.47M
   }
996
1.47M
   if(0 == this->m_last_state)
997
0
   {
998
0
      fail(regex_constants::error_badrepeat, std::distance(m_base, m_position), "Nothing to repeat.");
999
0
      return false;
1000
0
   }
1001
1.47M
   if(this->m_last_state->type == syntax_element_endmark)
1002
92.9k
   {
1003
      // insert a repeat before the '(' matching the last ')':
1004
92.9k
      insert_point = this->m_paren_start;
1005
92.9k
   }
1006
1.38M
   else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))
1007
1.15M
   {
1008
      // the last state was a literal with more than one character, split it in two:
1009
1.15M
      re_literal* lit = static_cast<re_literal*>(this->m_last_state);
1010
1.15M
      charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];
1011
1.15M
      lit->length -= 1;
1012
      // now append new state:
1013
1.15M
      lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
1014
1.15M
      lit->length = 1;
1015
1.15M
      (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;
1016
1.15M
      insert_point = this->getoffset(this->m_last_state);
1017
1.15M
   }
1018
231k
   else
1019
231k
   {
1020
      // repeat the last state whatever it was, need to add some error checking here:
1021
231k
      switch(this->m_last_state->type)
1022
231k
      {
1023
0
      case syntax_element_start_line:
1024
1
      case syntax_element_end_line:
1025
1
      case syntax_element_word_boundary:
1026
1
      case syntax_element_within_word:
1027
1
      case syntax_element_word_start:
1028
1
      case syntax_element_word_end:
1029
1
      case syntax_element_buffer_start:
1030
1
      case syntax_element_buffer_end:
1031
1
      case syntax_element_alt:
1032
1
      case syntax_element_soft_buffer_end:
1033
1
      case syntax_element_restart_continue:
1034
4
      case syntax_element_jump:
1035
5
      case syntax_element_startmark:
1036
5
      case syntax_element_backstep:
1037
5
      case syntax_element_toggle_case:
1038
         // can't legally repeat any of the above:
1039
5
         fail(regex_constants::error_badrepeat, m_position - m_base);
1040
5
         return false;
1041
231k
      default:
1042
         // do nothing...
1043
231k
         break;
1044
231k
      }
1045
231k
      insert_point = this->getoffset(this->m_last_state);
1046
231k
   }
1047
   //
1048
   // OK we now know what to repeat, so insert the repeat around it:
1049
   //
1050
1.47M
   re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));
1051
1.47M
   rep->min = low;
1052
1.47M
   rep->max = high;
1053
1.47M
   rep->greedy = greedy;
1054
1.47M
   rep->leading = false;
1055
   // store our repeater position for later:
1056
1.47M
   std::ptrdiff_t rep_off = this->getoffset(rep);
1057
   // and append a back jump to the repeat:
1058
1.47M
   re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));
1059
1.47M
   jmp->alt.i = rep_off - this->getoffset(jmp);
1060
1.47M
   this->m_pdata->m_data.align();
1061
   // now fill in the alt jump for the repeat:
1062
1.47M
   rep = static_cast<re_repeat*>(this->getaddress(rep_off));
1063
1.47M
   rep->alt.i = this->m_pdata->m_data.size() - rep_off;
1064
   //
1065
   // If the repeat is possessive then bracket the repeat with a (?>...)
1066
   // independent sub-expression construct:
1067
   //
1068
1.47M
   if(possessive)
1069
6.07k
   {
1070
6.07k
      if(m_position != m_end)
1071
6.07k
      {
1072
         //
1073
         // Check for illegal following quantifier, we have to do this here, because
1074
         // the extra states we insert below circumvents our usual error checking :-(
1075
         //
1076
6.07k
         bool contin = false;
1077
6.07k
         do
1078
6.11k
         {
1079
6.11k
            if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
1080
743
            {
1081
               // whitespace skip:
1082
744
               while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1083
1
                  ++m_position;
1084
743
            }
1085
6.11k
            if (m_position != m_end)
1086
6.11k
            {
1087
6.11k
               switch (this->m_traits.syntax_type(*m_position))
1088
6.11k
               {
1089
0
               case regex_constants::syntax_star:
1090
0
               case regex_constants::syntax_plus:
1091
0
               case regex_constants::syntax_question:
1092
0
               case regex_constants::syntax_open_brace:
1093
0
                  fail(regex_constants::error_badrepeat, m_position - m_base);
1094
0
                  return false;
1095
154
               case regex_constants::syntax_open_mark:
1096
                  // Do we have a comment?  If so we need to skip it here...
1097
154
                  if ((m_position + 2 < m_end) && this->m_traits.syntax_type(*(m_position + 1)) == regex_constants::syntax_question
1098
154
                     && this->m_traits.syntax_type(*(m_position + 2)) == regex_constants::syntax_hash)
1099
37
                  {
1100
162
                     while ((m_position != m_end)
1101
162
                        && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark)) {
1102
125
                     }
1103
37
                     contin = true;
1104
37
                  }
1105
117
                  else
1106
117
                     contin = false;
1107
154
                  break;
1108
5.95k
               default:
1109
5.95k
                  contin = false;
1110
6.11k
               }
1111
6.11k
            }
1112
0
            else
1113
0
               contin = false;
1114
6.11k
         } while (contin);
1115
6.07k
      }
1116
6.07k
      re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
1117
6.07k
      pb->index = -3;
1118
6.07k
      pb->icase = this->flags() & regbase::icase;
1119
6.07k
      jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));
1120
6.07k
      this->m_pdata->m_data.align();
1121
6.07k
      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
1122
6.07k
      pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
1123
6.07k
      pb->index = -3;
1124
6.07k
      pb->icase = this->flags() & regbase::icase;
1125
6.07k
   }
1126
1.47M
   return true;
1127
1.47M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_repeat(unsigned long, unsigned long)
Line
Count
Source
961
1.47M
{
962
1.47M
   bool greedy = true;
963
1.47M
   bool possessive = false;
964
1.47M
   std::size_t insert_point;
965
   // 
966
   // when we get to here we may have a non-greedy ? mark still to come:
967
   //
968
1.47M
   if((m_position != m_end) 
969
1.47M
      && (
970
1.47M
            (0 == (this->flags() & (regbase::main_option_type | regbase::no_perl_ex)))
971
1.47M
            || ((regbase::basic_syntax_group|regbase::emacs_ex) == (this->flags() & (regbase::main_option_type | regbase::emacs_ex)))
972
1.47M
         )
973
1.47M
      )
974
1.47M
   {
975
      // OK we have a perl or emacs regex, check for a '?':
976
1.47M
      if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
977
6.02k
      {
978
         // whitespace skip:
979
6.18k
         while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
980
166
            ++m_position;
981
6.02k
      }
982
1.47M
      if((m_position != m_end) && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question))
983
35.4k
      {
984
35.4k
         greedy = false;
985
35.4k
         ++m_position;
986
35.4k
      }
987
      // for perl regexes only check for possessive ++ repeats.
988
1.47M
      if((m_position != m_end)
989
1.47M
         && (0 == (this->flags() & regbase::main_option_type)) 
990
1.47M
         && (this->m_traits.syntax_type(*m_position) == regex_constants::syntax_plus))
991
6.07k
      {
992
6.07k
         possessive = true;
993
6.07k
         ++m_position;
994
6.07k
      }
995
1.47M
   }
996
1.47M
   if(0 == this->m_last_state)
997
0
   {
998
0
      fail(regex_constants::error_badrepeat, std::distance(m_base, m_position), "Nothing to repeat.");
999
0
      return false;
1000
0
   }
1001
1.47M
   if(this->m_last_state->type == syntax_element_endmark)
1002
92.9k
   {
1003
      // insert a repeat before the '(' matching the last ')':
1004
92.9k
      insert_point = this->m_paren_start;
1005
92.9k
   }
1006
1.38M
   else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))
1007
1.15M
   {
1008
      // the last state was a literal with more than one character, split it in two:
1009
1.15M
      re_literal* lit = static_cast<re_literal*>(this->m_last_state);
1010
1.15M
      charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];
1011
1.15M
      lit->length -= 1;
1012
      // now append new state:
1013
1.15M
      lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
1014
1.15M
      lit->length = 1;
1015
1.15M
      (static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;
1016
1.15M
      insert_point = this->getoffset(this->m_last_state);
1017
1.15M
   }
1018
231k
   else
1019
231k
   {
1020
      // repeat the last state whatever it was, need to add some error checking here:
1021
231k
      switch(this->m_last_state->type)
1022
231k
      {
1023
0
      case syntax_element_start_line:
1024
1
      case syntax_element_end_line:
1025
1
      case syntax_element_word_boundary:
1026
1
      case syntax_element_within_word:
1027
1
      case syntax_element_word_start:
1028
1
      case syntax_element_word_end:
1029
1
      case syntax_element_buffer_start:
1030
1
      case syntax_element_buffer_end:
1031
1
      case syntax_element_alt:
1032
1
      case syntax_element_soft_buffer_end:
1033
1
      case syntax_element_restart_continue:
1034
4
      case syntax_element_jump:
1035
5
      case syntax_element_startmark:
1036
5
      case syntax_element_backstep:
1037
5
      case syntax_element_toggle_case:
1038
         // can't legally repeat any of the above:
1039
5
         fail(regex_constants::error_badrepeat, m_position - m_base);
1040
5
         return false;
1041
231k
      default:
1042
         // do nothing...
1043
231k
         break;
1044
231k
      }
1045
231k
      insert_point = this->getoffset(this->m_last_state);
1046
231k
   }
1047
   //
1048
   // OK we now know what to repeat, so insert the repeat around it:
1049
   //
1050
1.47M
   re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));
1051
1.47M
   rep->min = low;
1052
1.47M
   rep->max = high;
1053
1.47M
   rep->greedy = greedy;
1054
1.47M
   rep->leading = false;
1055
   // store our repeater position for later:
1056
1.47M
   std::ptrdiff_t rep_off = this->getoffset(rep);
1057
   // and append a back jump to the repeat:
1058
1.47M
   re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));
1059
1.47M
   jmp->alt.i = rep_off - this->getoffset(jmp);
1060
1.47M
   this->m_pdata->m_data.align();
1061
   // now fill in the alt jump for the repeat:
1062
1.47M
   rep = static_cast<re_repeat*>(this->getaddress(rep_off));
1063
1.47M
   rep->alt.i = this->m_pdata->m_data.size() - rep_off;
1064
   //
1065
   // If the repeat is possessive then bracket the repeat with a (?>...)
1066
   // independent sub-expression construct:
1067
   //
1068
1.47M
   if(possessive)
1069
6.07k
   {
1070
6.07k
      if(m_position != m_end)
1071
6.07k
      {
1072
         //
1073
         // Check for illegal following quantifier, we have to do this here, because
1074
         // the extra states we insert below circumvents our usual error checking :-(
1075
         //
1076
6.07k
         bool contin = false;
1077
6.07k
         do
1078
6.11k
         {
1079
6.11k
            if ((this->flags() & (regbase::main_option_type | regbase::mod_x | regbase::no_perl_ex)) == regbase::mod_x)
1080
743
            {
1081
               // whitespace skip:
1082
744
               while ((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1083
1
                  ++m_position;
1084
743
            }
1085
6.11k
            if (m_position != m_end)
1086
6.11k
            {
1087
6.11k
               switch (this->m_traits.syntax_type(*m_position))
1088
6.11k
               {
1089
0
               case regex_constants::syntax_star:
1090
0
               case regex_constants::syntax_plus:
1091
0
               case regex_constants::syntax_question:
1092
0
               case regex_constants::syntax_open_brace:
1093
0
                  fail(regex_constants::error_badrepeat, m_position - m_base);
1094
0
                  return false;
1095
154
               case regex_constants::syntax_open_mark:
1096
                  // Do we have a comment?  If so we need to skip it here...
1097
154
                  if ((m_position + 2 < m_end) && this->m_traits.syntax_type(*(m_position + 1)) == regex_constants::syntax_question
1098
154
                     && this->m_traits.syntax_type(*(m_position + 2)) == regex_constants::syntax_hash)
1099
37
                  {
1100
162
                     while ((m_position != m_end)
1101
162
                        && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark)) {
1102
125
                     }
1103
37
                     contin = true;
1104
37
                  }
1105
117
                  else
1106
117
                     contin = false;
1107
154
                  break;
1108
5.95k
               default:
1109
5.95k
                  contin = false;
1110
6.11k
               }
1111
6.11k
            }
1112
0
            else
1113
0
               contin = false;
1114
6.11k
         } while (contin);
1115
6.07k
      }
1116
6.07k
      re_brace* pb = static_cast<re_brace*>(this->insert_state(insert_point, syntax_element_startmark, sizeof(re_brace)));
1117
6.07k
      pb->index = -3;
1118
6.07k
      pb->icase = this->flags() & regbase::icase;
1119
6.07k
      jmp = static_cast<re_jump*>(this->insert_state(insert_point + sizeof(re_brace), syntax_element_jump, sizeof(re_jump)));
1120
6.07k
      this->m_pdata->m_data.align();
1121
6.07k
      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
1122
6.07k
      pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
1123
6.07k
      pb->index = -3;
1124
6.07k
      pb->icase = this->flags() & regbase::icase;
1125
6.07k
   }
1126
1.47M
   return true;
1127
1.47M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_repeat(unsigned long, unsigned long)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_repeat(unsigned long, unsigned long)
1128
1129
template <class charT, class traits>
1130
bool basic_regex_parser<charT, traits>::parse_repeat_range(bool isbasic)
1131
19.2k
{
1132
19.2k
   static const char incomplete_message[] = "Missing } in quantified repetition.";
1133
   //
1134
   // parse a repeat-range:
1135
   //
1136
19.2k
   std::size_t min, max;
1137
19.2k
   std::intmax_t v;
1138
   // skip whitespace:
1139
19.4k
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1140
183
      ++m_position;
1141
19.2k
   if(this->m_position == this->m_end)
1142
0
   {
1143
0
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1144
0
      {
1145
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1146
0
         return false;
1147
0
      }
1148
      // Treat the opening '{' as a literal character, rewind to start of error:
1149
0
      --m_position;
1150
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1151
0
      return parse_literal();
1152
0
   }
1153
   // get min:
1154
19.2k
   v = this->m_traits.toi(m_position, m_end, 10);
1155
   // skip whitespace:
1156
19.2k
   if((v < 0) || (v > umax()))
1157
8.63k
   {
1158
8.63k
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1159
0
      {
1160
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1161
0
         return false;
1162
0
      }
1163
      // Treat the opening '{' as a literal character, rewind to start of error:
1164
8.63k
      --m_position;
1165
8.86k
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1166
8.63k
      return parse_literal();
1167
8.63k
   }
1168
10.6k
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1169
56
      ++m_position;
1170
10.6k
   if(this->m_position == this->m_end)
1171
3
   {
1172
3
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1173
0
      {
1174
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1175
0
         return false;
1176
0
      }
1177
      // Treat the opening '{' as a literal character, rewind to start of error:
1178
3
      --m_position;
1179
10
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1180
3
      return parse_literal();
1181
3
   }
1182
10.6k
   min = static_cast<std::size_t>(v);
1183
   // see if we have a comma:
1184
10.6k
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)
1185
958
   {
1186
      // move on and error check:
1187
958
      ++m_position;
1188
      // skip whitespace:
1189
959
      while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1190
1
         ++m_position;
1191
958
      if(this->m_position == this->m_end)
1192
2
      {
1193
2
         if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1194
0
         {
1195
0
            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1196
0
            return false;
1197
0
         }
1198
         // Treat the opening '{' as a literal character, rewind to start of error:
1199
2
         --m_position;
1200
6
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1201
2
         return parse_literal();
1202
2
      }
1203
      // get the value if any:
1204
956
      v = this->m_traits.toi(m_position, m_end, 10);
1205
956
      max = ((v >= 0) && (v < umax())) ? (std::size_t)v : (std::numeric_limits<std::size_t>::max)();
1206
956
   }
1207
9.64k
   else
1208
9.64k
   {
1209
      // no comma, max = min:
1210
9.64k
      max = min;
1211
9.64k
   }
1212
   // skip whitespace:
1213
10.6k
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1214
0
      ++m_position;
1215
   // OK now check trailing }:
1216
10.6k
   if(this->m_position == this->m_end)
1217
1
   {
1218
1
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1219
0
      {
1220
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1221
0
         return false;
1222
0
      }
1223
      // Treat the opening '{' as a literal character, rewind to start of error:
1224
1
      --m_position;
1225
24
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1226
1
      return parse_literal();
1227
1
   }
1228
10.6k
   if(isbasic)
1229
0
   {
1230
0
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)
1231
0
      {
1232
0
         ++m_position;
1233
0
         if(this->m_position == this->m_end)
1234
0
         {
1235
0
            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1236
0
            return false;
1237
0
         }
1238
0
      }
1239
0
      else
1240
0
      {
1241
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1242
0
         return false;
1243
0
      }
1244
0
   }
1245
10.6k
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)
1246
9.33k
      ++m_position;
1247
1.27k
   else
1248
1.27k
   {
1249
      // Treat the opening '{' as a literal character, rewind to start of error:
1250
1.27k
      --m_position;
1251
5.60k
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1252
1.27k
      return parse_literal();
1253
1.27k
   }
1254
   //
1255
   // finally go and add the repeat, unless error:
1256
   //
1257
9.33k
   if(min > max)
1258
0
   {
1259
      // Backtrack to error location:
1260
0
      m_position -= 2;
1261
0
      while(this->m_traits.isctype(*m_position, this->m_word_mask)) --m_position;
1262
0
         ++m_position;
1263
0
      fail(regex_constants::error_badbrace, m_position - m_base);
1264
0
      return false;
1265
0
   }
1266
9.33k
   return parse_repeat(min, max);
1267
9.33k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_repeat_range(bool)
Line
Count
Source
1131
19.2k
{
1132
19.2k
   static const char incomplete_message[] = "Missing } in quantified repetition.";
1133
   //
1134
   // parse a repeat-range:
1135
   //
1136
19.2k
   std::size_t min, max;
1137
19.2k
   std::intmax_t v;
1138
   // skip whitespace:
1139
19.4k
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1140
183
      ++m_position;
1141
19.2k
   if(this->m_position == this->m_end)
1142
0
   {
1143
0
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1144
0
      {
1145
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1146
0
         return false;
1147
0
      }
1148
      // Treat the opening '{' as a literal character, rewind to start of error:
1149
0
      --m_position;
1150
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1151
0
      return parse_literal();
1152
0
   }
1153
   // get min:
1154
19.2k
   v = this->m_traits.toi(m_position, m_end, 10);
1155
   // skip whitespace:
1156
19.2k
   if((v < 0) || (v > umax()))
1157
8.63k
   {
1158
8.63k
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1159
0
      {
1160
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1161
0
         return false;
1162
0
      }
1163
      // Treat the opening '{' as a literal character, rewind to start of error:
1164
8.63k
      --m_position;
1165
8.86k
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1166
8.63k
      return parse_literal();
1167
8.63k
   }
1168
10.6k
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1169
56
      ++m_position;
1170
10.6k
   if(this->m_position == this->m_end)
1171
3
   {
1172
3
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1173
0
      {
1174
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1175
0
         return false;
1176
0
      }
1177
      // Treat the opening '{' as a literal character, rewind to start of error:
1178
3
      --m_position;
1179
10
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1180
3
      return parse_literal();
1181
3
   }
1182
10.6k
   min = static_cast<std::size_t>(v);
1183
   // see if we have a comma:
1184
10.6k
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_comma)
1185
958
   {
1186
      // move on and error check:
1187
958
      ++m_position;
1188
      // skip whitespace:
1189
959
      while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1190
1
         ++m_position;
1191
958
      if(this->m_position == this->m_end)
1192
2
      {
1193
2
         if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1194
0
         {
1195
0
            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1196
0
            return false;
1197
0
         }
1198
         // Treat the opening '{' as a literal character, rewind to start of error:
1199
2
         --m_position;
1200
6
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1201
2
         return parse_literal();
1202
2
      }
1203
      // get the value if any:
1204
956
      v = this->m_traits.toi(m_position, m_end, 10);
1205
956
      max = ((v >= 0) && (v < umax())) ? (std::size_t)v : (std::numeric_limits<std::size_t>::max)();
1206
956
   }
1207
9.64k
   else
1208
9.64k
   {
1209
      // no comma, max = min:
1210
9.64k
      max = min;
1211
9.64k
   }
1212
   // skip whitespace:
1213
10.6k
   while((m_position != m_end) && this->m_traits.isctype(*m_position, this->m_mask_space))
1214
0
      ++m_position;
1215
   // OK now check trailing }:
1216
10.6k
   if(this->m_position == this->m_end)
1217
1
   {
1218
1
      if(this->flags() & (regbase::main_option_type | regbase::no_perl_ex))
1219
0
      {
1220
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1221
0
         return false;
1222
0
      }
1223
      // Treat the opening '{' as a literal character, rewind to start of error:
1224
1
      --m_position;
1225
24
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1226
1
      return parse_literal();
1227
1
   }
1228
10.6k
   if(isbasic)
1229
0
   {
1230
0
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_escape)
1231
0
      {
1232
0
         ++m_position;
1233
0
         if(this->m_position == this->m_end)
1234
0
         {
1235
0
            fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1236
0
            return false;
1237
0
         }
1238
0
      }
1239
0
      else
1240
0
      {
1241
0
         fail(regex_constants::error_brace, this->m_position - this->m_base, incomplete_message);
1242
0
         return false;
1243
0
      }
1244
0
   }
1245
10.6k
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_brace)
1246
9.33k
      ++m_position;
1247
1.27k
   else
1248
1.27k
   {
1249
      // Treat the opening '{' as a literal character, rewind to start of error:
1250
1.27k
      --m_position;
1251
5.60k
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_brace) --m_position;
1252
1.27k
      return parse_literal();
1253
1.27k
   }
1254
   //
1255
   // finally go and add the repeat, unless error:
1256
   //
1257
9.33k
   if(min > max)
1258
0
   {
1259
      // Backtrack to error location:
1260
0
      m_position -= 2;
1261
0
      while(this->m_traits.isctype(*m_position, this->m_word_mask)) --m_position;
1262
0
         ++m_position;
1263
0
      fail(regex_constants::error_badbrace, m_position - m_base);
1264
0
      return false;
1265
0
   }
1266
9.33k
   return parse_repeat(min, max);
1267
9.33k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_repeat_range(bool)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_repeat_range(bool)
1268
1269
template <class charT, class traits>
1270
bool basic_regex_parser<charT, traits>::parse_alt()
1271
7.43M
{
1272
   //
1273
   // error check: if there have been no previous states,
1274
   // or if the last state was a '(' then error:
1275
   //
1276
7.43M
   if(
1277
7.43M
      ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))
1278
7.43M
      &&
1279
7.43M
      !(
1280
6.14k
         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
1281
6.14k
           &&
1282
6.14k
         ((this->flags() & regbase::no_empty_expressions) == 0)
1283
6.14k
        )
1284
7.43M
      )
1285
0
   {
1286
0
      fail(regex_constants::error_empty, this->m_position - this->m_base, "A regular expression cannot start with the alternation operator |.");
1287
0
      return false;
1288
0
   }
1289
   //
1290
   // Reset mark count if required:
1291
   //
1292
7.43M
   if(m_max_mark < m_mark_count)
1293
43.9k
      m_max_mark = m_mark_count;
1294
7.43M
   if(m_mark_reset >= 0)
1295
3.97k
      m_mark_count = m_mark_reset;
1296
1297
7.43M
   ++m_position;
1298
   //
1299
   // we need to append a trailing jump: 
1300
   //
1301
7.43M
   re_syntax_base* pj = this->append_state(BOOST_REGEX_DETAIL_NS::syntax_element_jump, sizeof(re_jump));
1302
7.43M
   std::ptrdiff_t jump_offset = this->getoffset(pj);
1303
   //
1304
   // now insert the alternative:
1305
   //
1306
7.43M
   re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));
1307
7.43M
   jump_offset += re_alt_size;
1308
7.43M
   this->m_pdata->m_data.align();
1309
7.43M
   palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);
1310
   //
1311
   // update m_alt_insert_point so that the next alternate gets
1312
   // inserted at the start of the second of the two we've just created:
1313
   //
1314
7.43M
   this->m_alt_insert_point = this->m_pdata->m_data.size();
1315
   //
1316
   // the start of this alternative must have a case changes state
1317
   // if the current block has messed around with case changes:
1318
   //
1319
7.43M
   if(m_has_case_change)
1320
1.86M
   {
1321
1.86M
      static_cast<re_case*>(
1322
1.86M
         this->append_state(syntax_element_toggle_case, sizeof(re_case))
1323
1.86M
         )->icase = this->m_icase;
1324
1.86M
   }
1325
   //
1326
   // push the alternative onto our stack, a recursive
1327
   // implementation here is easier to understand (and faster
1328
   // as it happens), but causes all kinds of stack overflow problems
1329
   // on programs with small stacks (COM+).
1330
   //
1331
7.43M
   m_alt_jumps.push_back(jump_offset);
1332
7.43M
   return true;
1333
7.43M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_alt()
Line
Count
Source
1271
7.43M
{
1272
   //
1273
   // error check: if there have been no previous states,
1274
   // or if the last state was a '(' then error:
1275
   //
1276
7.43M
   if(
1277
7.43M
      ((this->m_last_state == 0) || (this->m_last_state->type == syntax_element_startmark))
1278
7.43M
      &&
1279
7.43M
      !(
1280
6.14k
         ((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group)
1281
6.14k
           &&
1282
6.14k
         ((this->flags() & regbase::no_empty_expressions) == 0)
1283
6.14k
        )
1284
7.43M
      )
1285
0
   {
1286
0
      fail(regex_constants::error_empty, this->m_position - this->m_base, "A regular expression cannot start with the alternation operator |.");
1287
0
      return false;
1288
0
   }
1289
   //
1290
   // Reset mark count if required:
1291
   //
1292
7.43M
   if(m_max_mark < m_mark_count)
1293
43.9k
      m_max_mark = m_mark_count;
1294
7.43M
   if(m_mark_reset >= 0)
1295
3.97k
      m_mark_count = m_mark_reset;
1296
1297
7.43M
   ++m_position;
1298
   //
1299
   // we need to append a trailing jump: 
1300
   //
1301
7.43M
   re_syntax_base* pj = this->append_state(BOOST_REGEX_DETAIL_NS::syntax_element_jump, sizeof(re_jump));
1302
7.43M
   std::ptrdiff_t jump_offset = this->getoffset(pj);
1303
   //
1304
   // now insert the alternative:
1305
   //
1306
7.43M
   re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));
1307
7.43M
   jump_offset += re_alt_size;
1308
7.43M
   this->m_pdata->m_data.align();
1309
7.43M
   palt->alt.i = this->m_pdata->m_data.size() - this->getoffset(palt);
1310
   //
1311
   // update m_alt_insert_point so that the next alternate gets
1312
   // inserted at the start of the second of the two we've just created:
1313
   //
1314
7.43M
   this->m_alt_insert_point = this->m_pdata->m_data.size();
1315
   //
1316
   // the start of this alternative must have a case changes state
1317
   // if the current block has messed around with case changes:
1318
   //
1319
7.43M
   if(m_has_case_change)
1320
1.86M
   {
1321
1.86M
      static_cast<re_case*>(
1322
1.86M
         this->append_state(syntax_element_toggle_case, sizeof(re_case))
1323
1.86M
         )->icase = this->m_icase;
1324
1.86M
   }
1325
   //
1326
   // push the alternative onto our stack, a recursive
1327
   // implementation here is easier to understand (and faster
1328
   // as it happens), but causes all kinds of stack overflow problems
1329
   // on programs with small stacks (COM+).
1330
   //
1331
7.43M
   m_alt_jumps.push_back(jump_offset);
1332
7.43M
   return true;
1333
7.43M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_alt()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_alt()
1334
1335
template <class charT, class traits>
1336
bool basic_regex_parser<charT, traits>::parse_set()
1337
82.2k
{
1338
82.2k
   static const char incomplete_message[] = "Character set declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
1339
82.2k
   ++m_position;
1340
82.2k
   if(m_position == m_end)
1341
2
   {
1342
2
      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1343
2
      return false;
1344
2
   }
1345
82.2k
   basic_char_set<charT, traits> char_set;
1346
1347
82.2k
   const charT* base = m_position;  // where the '[' was
1348
82.2k
   const charT* item_base = m_position;  // where the '[' or '^' was
1349
1350
9.03M
   while(m_position != m_end)
1351
9.03M
   {
1352
9.03M
      switch(this->m_traits.syntax_type(*m_position))
1353
9.03M
      {
1354
27.5k
      case regex_constants::syntax_caret:
1355
27.5k
         if(m_position == base)
1356
27.3k
         {
1357
27.3k
            char_set.negate();
1358
27.3k
            ++m_position;
1359
27.3k
            item_base = m_position;
1360
27.3k
         }
1361
209
         else
1362
209
            parse_set_literal(char_set);
1363
27.5k
         break;
1364
87.0k
      case regex_constants::syntax_close_set:
1365
87.0k
         if(m_position == item_base)
1366
4.88k
         {
1367
4.88k
            parse_set_literal(char_set);
1368
4.88k
            break;
1369
4.88k
         }
1370
82.1k
         else
1371
82.1k
         {
1372
82.1k
            ++m_position;
1373
82.1k
            if(0 == this->append_set(char_set))
1374
2
            {
1375
2
               fail(regex_constants::error_ctype, m_position - m_base);
1376
2
               return false;
1377
2
            }
1378
82.1k
         }
1379
82.1k
         return true;
1380
31.1k
      case regex_constants::syntax_open_set:
1381
31.1k
         if(parse_inner_set(char_set))
1382
31.1k
            break;
1383
61
         return true;
1384
30.9k
      case regex_constants::syntax_escape:
1385
30.9k
         {
1386
            // 
1387
            // look ahead and see if this is a character class shortcut
1388
            // \d \w \s etc...
1389
            //
1390
30.9k
            ++m_position;
1391
30.9k
            if(this->m_traits.escape_syntax_type(*m_position)
1392
30.9k
               == regex_constants::escape_type_class)
1393
77
            {
1394
77
               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
1395
77
               if(m != 0)
1396
73
               {
1397
73
                  char_set.add_class(m);
1398
73
                  ++m_position;
1399
73
                  break;
1400
73
               }
1401
77
            }
1402
30.9k
            else if(this->m_traits.escape_syntax_type(*m_position)
1403
30.9k
               == regex_constants::escape_type_not_class)
1404
59
            {
1405
               // negated character class:
1406
59
               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
1407
59
               if(m != 0)
1408
47
               {
1409
47
                  char_set.add_negated_class(m);
1410
47
                  ++m_position;
1411
47
                  break;
1412
47
               }
1413
59
            }
1414
            // not a character class, just a regular escape:
1415
30.8k
            --m_position;
1416
30.8k
            parse_set_literal(char_set);
1417
30.8k
            break;
1418
30.9k
         }
1419
8.85M
      default:
1420
8.85M
         parse_set_literal(char_set);
1421
8.85M
         break;
1422
9.03M
      }
1423
9.03M
   }
1424
0
   return m_position != m_end;
1425
82.2k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_set()
Line
Count
Source
1337
82.2k
{
1338
82.2k
   static const char incomplete_message[] = "Character set declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
1339
82.2k
   ++m_position;
1340
82.2k
   if(m_position == m_end)
1341
2
   {
1342
2
      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1343
2
      return false;
1344
2
   }
1345
82.2k
   basic_char_set<charT, traits> char_set;
1346
1347
82.2k
   const charT* base = m_position;  // where the '[' was
1348
82.2k
   const charT* item_base = m_position;  // where the '[' or '^' was
1349
1350
9.03M
   while(m_position != m_end)
1351
9.03M
   {
1352
9.03M
      switch(this->m_traits.syntax_type(*m_position))
1353
9.03M
      {
1354
27.5k
      case regex_constants::syntax_caret:
1355
27.5k
         if(m_position == base)
1356
27.3k
         {
1357
27.3k
            char_set.negate();
1358
27.3k
            ++m_position;
1359
27.3k
            item_base = m_position;
1360
27.3k
         }
1361
209
         else
1362
209
            parse_set_literal(char_set);
1363
27.5k
         break;
1364
87.0k
      case regex_constants::syntax_close_set:
1365
87.0k
         if(m_position == item_base)
1366
4.88k
         {
1367
4.88k
            parse_set_literal(char_set);
1368
4.88k
            break;
1369
4.88k
         }
1370
82.1k
         else
1371
82.1k
         {
1372
82.1k
            ++m_position;
1373
82.1k
            if(0 == this->append_set(char_set))
1374
2
            {
1375
2
               fail(regex_constants::error_ctype, m_position - m_base);
1376
2
               return false;
1377
2
            }
1378
82.1k
         }
1379
82.1k
         return true;
1380
31.1k
      case regex_constants::syntax_open_set:
1381
31.1k
         if(parse_inner_set(char_set))
1382
31.1k
            break;
1383
61
         return true;
1384
30.9k
      case regex_constants::syntax_escape:
1385
30.9k
         {
1386
            // 
1387
            // look ahead and see if this is a character class shortcut
1388
            // \d \w \s etc...
1389
            //
1390
30.9k
            ++m_position;
1391
30.9k
            if(this->m_traits.escape_syntax_type(*m_position)
1392
30.9k
               == regex_constants::escape_type_class)
1393
77
            {
1394
77
               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
1395
77
               if(m != 0)
1396
73
               {
1397
73
                  char_set.add_class(m);
1398
73
                  ++m_position;
1399
73
                  break;
1400
73
               }
1401
77
            }
1402
30.9k
            else if(this->m_traits.escape_syntax_type(*m_position)
1403
30.9k
               == regex_constants::escape_type_not_class)
1404
59
            {
1405
               // negated character class:
1406
59
               char_class_type m = this->m_traits.lookup_classname(m_position, m_position+1);
1407
59
               if(m != 0)
1408
47
               {
1409
47
                  char_set.add_negated_class(m);
1410
47
                  ++m_position;
1411
47
                  break;
1412
47
               }
1413
59
            }
1414
            // not a character class, just a regular escape:
1415
30.8k
            --m_position;
1416
30.8k
            parse_set_literal(char_set);
1417
30.8k
            break;
1418
30.9k
         }
1419
8.85M
      default:
1420
8.85M
         parse_set_literal(char_set);
1421
8.85M
         break;
1422
9.03M
      }
1423
9.03M
   }
1424
0
   return m_position != m_end;
1425
82.2k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_set()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_set()
1426
1427
template <class charT, class traits>
1428
bool basic_regex_parser<charT, traits>::parse_inner_set(basic_char_set<charT, traits>& char_set)
1429
31.1k
{
1430
31.1k
   static const char incomplete_message[] = "Character class declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
1431
   //
1432
   // we have either a character class [:name:]
1433
   // a collating element [.name.]
1434
   // or an equivalence class [=name=]
1435
   //
1436
31.1k
   if(m_end == ++m_position)
1437
0
   {
1438
0
      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1439
0
      return false;
1440
0
   }
1441
31.1k
   switch(this->m_traits.syntax_type(*m_position))
1442
31.1k
   {
1443
150
   case regex_constants::syntax_dot:
1444
      //
1445
      // a collating element is treated as a literal:
1446
      //
1447
150
      --m_position;
1448
150
      parse_set_literal(char_set);
1449
150
      return true;
1450
19.9k
   case regex_constants::syntax_colon:
1451
19.9k
      {
1452
      // check that character classes are actually enabled:
1453
19.9k
      if((this->flags() & (regbase::main_option_type | regbase::no_char_classes)) 
1454
19.9k
         == (regbase::basic_syntax_group  | regbase::no_char_classes))
1455
0
      {
1456
0
         --m_position;
1457
0
         parse_set_literal(char_set);
1458
0
         return true;
1459
0
      }
1460
      // skip the ':'
1461
19.9k
      if(m_end == ++m_position)
1462
0
      {
1463
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1464
0
         return false;
1465
0
      }
1466
19.9k
      const charT* name_first = m_position;
1467
      // skip at least one character, then find the matching ':]'
1468
19.9k
      if(m_end == ++m_position)
1469
1
      {
1470
1
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1471
1
         return false;
1472
1
      }
1473
5.70M
      while((m_position != m_end) 
1474
5.70M
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon)) 
1475
5.68M
         ++m_position;
1476
19.9k
      const charT* name_last = m_position;
1477
19.9k
      if(m_end == m_position)
1478
0
      {
1479
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1480
0
         return false;
1481
0
      }
1482
19.9k
      if((m_end == ++m_position) 
1483
19.9k
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1484
0
      {
1485
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1486
0
         return false;
1487
0
      }
1488
      //
1489
      // check for negated class:
1490
      //
1491
19.9k
      bool negated = false;
1492
19.9k
      if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)
1493
0
      {
1494
0
         ++name_first;
1495
0
         negated = true;
1496
0
      }
1497
19.9k
      typedef typename traits::char_class_type m_type;
1498
19.9k
      m_type m = this->m_traits.lookup_classname(name_first, name_last);
1499
19.9k
      if(m == 0)
1500
44
      {
1501
44
         if(char_set.empty() && (name_last - name_first == 1))
1502
32
         {
1503
            // maybe a special case:
1504
32
            ++m_position;
1505
32
            if( (m_position != m_end) 
1506
32
               && (this->m_traits.syntax_type(*m_position) 
1507
32
                  == regex_constants::syntax_close_set))
1508
32
            {
1509
32
               if(this->m_traits.escape_syntax_type(*name_first) 
1510
32
                  == regex_constants::escape_type_left_word)
1511
32
               {
1512
32
                  ++m_position;
1513
32
                  this->append_state(syntax_element_word_start);
1514
32
                  return false;
1515
32
               }
1516
0
               if(this->m_traits.escape_syntax_type(*name_first) 
1517
0
                  == regex_constants::escape_type_right_word)
1518
0
               {
1519
0
                  ++m_position;
1520
0
                  this->append_state(syntax_element_word_end);
1521
0
                  return false;
1522
0
               }
1523
0
            }
1524
32
         }
1525
12
         fail(regex_constants::error_ctype, name_first - m_base);
1526
12
         return false;
1527
44
      }
1528
19.9k
      if(!negated)
1529
19.9k
         char_set.add_class(m);
1530
0
      else
1531
0
         char_set.add_negated_class(m);
1532
19.9k
      ++m_position;
1533
19.9k
      break;
1534
19.9k
   }
1535
694
   case regex_constants::syntax_equal:
1536
694
      {
1537
      // skip the '='
1538
694
      if(m_end == ++m_position)
1539
0
      {
1540
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1541
0
         return false;
1542
0
      }
1543
694
      const charT* name_first = m_position;
1544
      // skip at least one character, then find the matching '=]'
1545
694
      if(m_end == ++m_position)
1546
0
      {
1547
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1548
0
         return false;
1549
0
      }
1550
4.13M
      while((m_position != m_end) 
1551
4.13M
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)) 
1552
4.13M
         ++m_position;
1553
694
      const charT* name_last = m_position;
1554
694
      if(m_end == m_position)
1555
0
      {
1556
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1557
0
         return false;
1558
0
      }
1559
694
      if((m_end == ++m_position) 
1560
694
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1561
3
      {
1562
3
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1563
3
         return false;
1564
3
      }
1565
691
      string_type m = this->m_traits.lookup_collatename(name_first, name_last);
1566
691
      if(m.empty() || (m.size() > 2))
1567
9
      {
1568
9
         fail(regex_constants::error_collate, name_first - m_base);
1569
9
         return false;
1570
9
      }
1571
682
      digraph<charT> d;
1572
682
      d.first = m[0];
1573
682
      if(m.size() > 1)
1574
71
         d.second = m[1];
1575
611
      else
1576
611
         d.second = 0;
1577
682
      char_set.add_equivalent(d);
1578
682
      ++m_position;
1579
682
      break;
1580
691
   }
1581
10.3k
   default:
1582
10.3k
      --m_position;
1583
10.3k
      parse_set_literal(char_set);
1584
10.3k
      break;
1585
31.1k
   }
1586
30.9k
   return true;
1587
31.1k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_inner_set(boost::re_detail_500::basic_char_set<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >&)
Line
Count
Source
1429
31.1k
{
1430
31.1k
   static const char incomplete_message[] = "Character class declaration starting with [ terminated prematurely - either no ] was found or the set had no content.";
1431
   //
1432
   // we have either a character class [:name:]
1433
   // a collating element [.name.]
1434
   // or an equivalence class [=name=]
1435
   //
1436
31.1k
   if(m_end == ++m_position)
1437
0
   {
1438
0
      fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1439
0
      return false;
1440
0
   }
1441
31.1k
   switch(this->m_traits.syntax_type(*m_position))
1442
31.1k
   {
1443
150
   case regex_constants::syntax_dot:
1444
      //
1445
      // a collating element is treated as a literal:
1446
      //
1447
150
      --m_position;
1448
150
      parse_set_literal(char_set);
1449
150
      return true;
1450
19.9k
   case regex_constants::syntax_colon:
1451
19.9k
      {
1452
      // check that character classes are actually enabled:
1453
19.9k
      if((this->flags() & (regbase::main_option_type | regbase::no_char_classes)) 
1454
19.9k
         == (regbase::basic_syntax_group  | regbase::no_char_classes))
1455
0
      {
1456
0
         --m_position;
1457
0
         parse_set_literal(char_set);
1458
0
         return true;
1459
0
      }
1460
      // skip the ':'
1461
19.9k
      if(m_end == ++m_position)
1462
0
      {
1463
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1464
0
         return false;
1465
0
      }
1466
19.9k
      const charT* name_first = m_position;
1467
      // skip at least one character, then find the matching ':]'
1468
19.9k
      if(m_end == ++m_position)
1469
1
      {
1470
1
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1471
1
         return false;
1472
1
      }
1473
5.70M
      while((m_position != m_end) 
1474
5.70M
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_colon)) 
1475
5.68M
         ++m_position;
1476
19.9k
      const charT* name_last = m_position;
1477
19.9k
      if(m_end == m_position)
1478
0
      {
1479
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1480
0
         return false;
1481
0
      }
1482
19.9k
      if((m_end == ++m_position) 
1483
19.9k
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1484
0
      {
1485
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1486
0
         return false;
1487
0
      }
1488
      //
1489
      // check for negated class:
1490
      //
1491
19.9k
      bool negated = false;
1492
19.9k
      if(this->m_traits.syntax_type(*name_first) == regex_constants::syntax_caret)
1493
0
      {
1494
0
         ++name_first;
1495
0
         negated = true;
1496
0
      }
1497
19.9k
      typedef typename traits::char_class_type m_type;
1498
19.9k
      m_type m = this->m_traits.lookup_classname(name_first, name_last);
1499
19.9k
      if(m == 0)
1500
44
      {
1501
44
         if(char_set.empty() && (name_last - name_first == 1))
1502
32
         {
1503
            // maybe a special case:
1504
32
            ++m_position;
1505
32
            if( (m_position != m_end) 
1506
32
               && (this->m_traits.syntax_type(*m_position) 
1507
32
                  == regex_constants::syntax_close_set))
1508
32
            {
1509
32
               if(this->m_traits.escape_syntax_type(*name_first) 
1510
32
                  == regex_constants::escape_type_left_word)
1511
32
               {
1512
32
                  ++m_position;
1513
32
                  this->append_state(syntax_element_word_start);
1514
32
                  return false;
1515
32
               }
1516
0
               if(this->m_traits.escape_syntax_type(*name_first) 
1517
0
                  == regex_constants::escape_type_right_word)
1518
0
               {
1519
0
                  ++m_position;
1520
0
                  this->append_state(syntax_element_word_end);
1521
0
                  return false;
1522
0
               }
1523
0
            }
1524
32
         }
1525
12
         fail(regex_constants::error_ctype, name_first - m_base);
1526
12
         return false;
1527
44
      }
1528
19.9k
      if(!negated)
1529
19.9k
         char_set.add_class(m);
1530
0
      else
1531
0
         char_set.add_negated_class(m);
1532
19.9k
      ++m_position;
1533
19.9k
      break;
1534
19.9k
   }
1535
694
   case regex_constants::syntax_equal:
1536
694
      {
1537
      // skip the '='
1538
694
      if(m_end == ++m_position)
1539
0
      {
1540
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1541
0
         return false;
1542
0
      }
1543
694
      const charT* name_first = m_position;
1544
      // skip at least one character, then find the matching '=]'
1545
694
      if(m_end == ++m_position)
1546
0
      {
1547
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1548
0
         return false;
1549
0
      }
1550
4.13M
      while((m_position != m_end) 
1551
4.13M
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)) 
1552
4.13M
         ++m_position;
1553
694
      const charT* name_last = m_position;
1554
694
      if(m_end == m_position)
1555
0
      {
1556
0
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1557
0
         return false;
1558
0
      }
1559
694
      if((m_end == ++m_position) 
1560
694
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1561
3
      {
1562
3
         fail(regex_constants::error_brack, m_position - m_base, incomplete_message);
1563
3
         return false;
1564
3
      }
1565
691
      string_type m = this->m_traits.lookup_collatename(name_first, name_last);
1566
691
      if(m.empty() || (m.size() > 2))
1567
9
      {
1568
9
         fail(regex_constants::error_collate, name_first - m_base);
1569
9
         return false;
1570
9
      }
1571
682
      digraph<charT> d;
1572
682
      d.first = m[0];
1573
682
      if(m.size() > 1)
1574
71
         d.second = m[1];
1575
611
      else
1576
611
         d.second = 0;
1577
682
      char_set.add_equivalent(d);
1578
682
      ++m_position;
1579
682
      break;
1580
691
   }
1581
10.3k
   default:
1582
10.3k
      --m_position;
1583
10.3k
      parse_set_literal(char_set);
1584
10.3k
      break;
1585
31.1k
   }
1586
30.9k
   return true;
1587
31.1k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_inner_set(boost::re_detail_500::basic_char_set<char, boost::c_regex_traits<char> >&)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_inner_set(boost::re_detail_500::basic_char_set<wchar_t, boost::c_regex_traits<wchar_t> >&)
1588
1589
template <class charT, class traits>
1590
void basic_regex_parser<charT, traits>::parse_set_literal(basic_char_set<charT, traits>& char_set)
1591
8.90M
{
1592
8.90M
   digraph<charT> start_range(get_next_set_literal(char_set));
1593
8.90M
   if(m_end == m_position)
1594
17
   {
1595
17
      fail(regex_constants::error_brack, m_position - m_base);
1596
17
      return;
1597
17
   }
1598
8.90M
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
1599
220k
   {
1600
      // we have a range:
1601
220k
      if(m_end == ++m_position)
1602
0
      {
1603
0
         fail(regex_constants::error_brack, m_position - m_base);
1604
0
         return;
1605
0
      }
1606
220k
      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)
1607
212k
      {
1608
212k
         digraph<charT> end_range = get_next_set_literal(char_set);
1609
212k
         char_set.add_range(start_range, end_range);
1610
212k
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
1611
2
         {
1612
2
            if(m_end == ++m_position)
1613
0
            {
1614
0
               fail(regex_constants::error_brack, m_position - m_base);
1615
0
               return;
1616
0
            }
1617
2
            if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)
1618
1
            {
1619
               // trailing - :
1620
1
               --m_position;
1621
1
               return;
1622
1
            }
1623
1
            fail(regex_constants::error_range, m_position - m_base);
1624
1
            return;
1625
2
         }
1626
212k
         return;
1627
212k
      }
1628
8.15k
      --m_position;
1629
8.15k
   }
1630
8.69M
   char_set.add_single(start_range);
1631
8.69M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_set_literal(boost::re_detail_500::basic_char_set<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >&)
Line
Count
Source
1591
8.90M
{
1592
8.90M
   digraph<charT> start_range(get_next_set_literal(char_set));
1593
8.90M
   if(m_end == m_position)
1594
17
   {
1595
17
      fail(regex_constants::error_brack, m_position - m_base);
1596
17
      return;
1597
17
   }
1598
8.90M
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
1599
220k
   {
1600
      // we have a range:
1601
220k
      if(m_end == ++m_position)
1602
0
      {
1603
0
         fail(regex_constants::error_brack, m_position - m_base);
1604
0
         return;
1605
0
      }
1606
220k
      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set)
1607
212k
      {
1608
212k
         digraph<charT> end_range = get_next_set_literal(char_set);
1609
212k
         char_set.add_range(start_range, end_range);
1610
212k
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_dash)
1611
2
         {
1612
2
            if(m_end == ++m_position)
1613
0
            {
1614
0
               fail(regex_constants::error_brack, m_position - m_base);
1615
0
               return;
1616
0
            }
1617
2
            if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_set)
1618
1
            {
1619
               // trailing - :
1620
1
               --m_position;
1621
1
               return;
1622
1
            }
1623
1
            fail(regex_constants::error_range, m_position - m_base);
1624
1
            return;
1625
2
         }
1626
212k
         return;
1627
212k
      }
1628
8.15k
      --m_position;
1629
8.15k
   }
1630
8.69M
   char_set.add_single(start_range);
1631
8.69M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_set_literal(boost::re_detail_500::basic_char_set<char, boost::c_regex_traits<char> >&)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_set_literal(boost::re_detail_500::basic_char_set<wchar_t, boost::c_regex_traits<wchar_t> >&)
1632
1633
template <class charT, class traits>
1634
digraph<charT> basic_regex_parser<charT, traits>::get_next_set_literal(basic_char_set<charT, traits>& char_set)
1635
9.11M
{
1636
9.11M
   digraph<charT> result;
1637
9.11M
   switch(this->m_traits.syntax_type(*m_position))
1638
9.11M
   {
1639
17.6k
   case regex_constants::syntax_dash:
1640
17.6k
      if(!char_set.empty())
1641
8.15k
      {
1642
         // see if we are at the end of the set:
1643
8.15k
         if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1644
2
         {
1645
2
            fail(regex_constants::error_range, m_position - m_base);
1646
2
            return result;
1647
2
         }
1648
8.15k
         --m_position;
1649
8.15k
      }
1650
17.6k
      result.first = *m_position++;
1651
17.6k
      return result;
1652
30.8k
   case regex_constants::syntax_escape:
1653
      // check to see if escapes are supported first:
1654
30.8k
      if(this->flags() & regex_constants::no_escape_in_lists)
1655
0
      {
1656
0
         result = *m_position++;
1657
0
         break;
1658
0
      }
1659
30.8k
      ++m_position;
1660
30.8k
      result = unescape_character();
1661
30.8k
      break;
1662
10.6k
   case regex_constants::syntax_open_set:
1663
10.6k
   {
1664
10.6k
      if(m_end == ++m_position)
1665
0
      {
1666
0
         fail(regex_constants::error_collate, m_position - m_base);
1667
0
         return result;
1668
0
      }
1669
10.6k
      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)
1670
10.4k
      {
1671
10.4k
         --m_position;
1672
10.4k
         result.first = *m_position;
1673
10.4k
         ++m_position;
1674
10.4k
         return result;
1675
10.4k
      }
1676
154
      if(m_end == ++m_position)
1677
2
      {
1678
2
         fail(regex_constants::error_collate, m_position - m_base);
1679
2
         return result;
1680
2
      }
1681
152
      const charT* name_first = m_position;
1682
      // skip at least one character, then find the matching ':]'
1683
152
      if(m_end == ++m_position)
1684
0
      {
1685
0
         fail(regex_constants::error_collate, name_first - m_base);
1686
0
         return result;
1687
0
      }
1688
391k
      while((m_position != m_end) 
1689
391k
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)) 
1690
391k
         ++m_position;
1691
152
      const charT* name_last = m_position;
1692
152
      if(m_end == m_position)
1693
0
      {
1694
0
         fail(regex_constants::error_collate, name_first - m_base);
1695
0
         return result;
1696
0
      }
1697
152
      if((m_end == ++m_position) 
1698
152
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1699
1
      {
1700
1
         fail(regex_constants::error_collate, name_first - m_base);
1701
1
         return result;
1702
1
      }
1703
151
      ++m_position;
1704
151
      string_type s = this->m_traits.lookup_collatename(name_first, name_last);
1705
151
      if(s.empty() || (s.size() > 2))
1706
1
      {
1707
1
         fail(regex_constants::error_collate, name_first - m_base);
1708
1
         return result;
1709
1
      }
1710
150
      result.first = s[0];
1711
150
      if(s.size() > 1)
1712
149
         result.second = s[1];
1713
1
      else
1714
1
         result.second = 0;
1715
150
      return result;
1716
151
   }
1717
9.05M
   default:
1718
9.05M
      result = *m_position++;
1719
9.11M
   }
1720
9.08M
   return result;
1721
9.11M
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::get_next_set_literal(boost::re_detail_500::basic_char_set<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >&)
Line
Count
Source
1635
9.11M
{
1636
9.11M
   digraph<charT> result;
1637
9.11M
   switch(this->m_traits.syntax_type(*m_position))
1638
9.11M
   {
1639
17.6k
   case regex_constants::syntax_dash:
1640
17.6k
      if(!char_set.empty())
1641
8.15k
      {
1642
         // see if we are at the end of the set:
1643
8.15k
         if((++m_position == m_end) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1644
2
         {
1645
2
            fail(regex_constants::error_range, m_position - m_base);
1646
2
            return result;
1647
2
         }
1648
8.15k
         --m_position;
1649
8.15k
      }
1650
17.6k
      result.first = *m_position++;
1651
17.6k
      return result;
1652
30.8k
   case regex_constants::syntax_escape:
1653
      // check to see if escapes are supported first:
1654
30.8k
      if(this->flags() & regex_constants::no_escape_in_lists)
1655
0
      {
1656
0
         result = *m_position++;
1657
0
         break;
1658
0
      }
1659
30.8k
      ++m_position;
1660
30.8k
      result = unescape_character();
1661
30.8k
      break;
1662
10.6k
   case regex_constants::syntax_open_set:
1663
10.6k
   {
1664
10.6k
      if(m_end == ++m_position)
1665
0
      {
1666
0
         fail(regex_constants::error_collate, m_position - m_base);
1667
0
         return result;
1668
0
      }
1669
10.6k
      if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)
1670
10.4k
      {
1671
10.4k
         --m_position;
1672
10.4k
         result.first = *m_position;
1673
10.4k
         ++m_position;
1674
10.4k
         return result;
1675
10.4k
      }
1676
154
      if(m_end == ++m_position)
1677
2
      {
1678
2
         fail(regex_constants::error_collate, m_position - m_base);
1679
2
         return result;
1680
2
      }
1681
152
      const charT* name_first = m_position;
1682
      // skip at least one character, then find the matching ':]'
1683
152
      if(m_end == ++m_position)
1684
0
      {
1685
0
         fail(regex_constants::error_collate, name_first - m_base);
1686
0
         return result;
1687
0
      }
1688
391k
      while((m_position != m_end) 
1689
391k
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_dot)) 
1690
391k
         ++m_position;
1691
152
      const charT* name_last = m_position;
1692
152
      if(m_end == m_position)
1693
0
      {
1694
0
         fail(regex_constants::error_collate, name_first - m_base);
1695
0
         return result;
1696
0
      }
1697
152
      if((m_end == ++m_position) 
1698
152
         || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_set))
1699
1
      {
1700
1
         fail(regex_constants::error_collate, name_first - m_base);
1701
1
         return result;
1702
1
      }
1703
151
      ++m_position;
1704
151
      string_type s = this->m_traits.lookup_collatename(name_first, name_last);
1705
151
      if(s.empty() || (s.size() > 2))
1706
1
      {
1707
1
         fail(regex_constants::error_collate, name_first - m_base);
1708
1
         return result;
1709
1
      }
1710
150
      result.first = s[0];
1711
150
      if(s.size() > 1)
1712
149
         result.second = s[1];
1713
1
      else
1714
1
         result.second = 0;
1715
150
      return result;
1716
151
   }
1717
9.05M
   default:
1718
9.05M
      result = *m_position++;
1719
9.11M
   }
1720
9.08M
   return result;
1721
9.11M
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::get_next_set_literal(boost::re_detail_500::basic_char_set<char, boost::c_regex_traits<char> >&)
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::get_next_set_literal(boost::re_detail_500::basic_char_set<wchar_t, boost::c_regex_traits<wchar_t> >&)
1722
1723
//
1724
// does a value fit in the specified charT type?
1725
//
1726
template <class charT>
1727
bool valid_value(charT, std::intmax_t v, const std::integral_constant<bool, true>&)
1728
2.03k
{
1729
2.03k
   return (v >> (sizeof(charT) * CHAR_BIT)) == 0;
1730
2.03k
}
bool boost::re_detail_500::valid_value<char>(char, long, std::__1::integral_constant<bool, true> const&)
Line
Count
Source
1728
2.03k
{
1729
2.03k
   return (v >> (sizeof(charT) * CHAR_BIT)) == 0;
1730
2.03k
}
Unexecuted instantiation: bool boost::re_detail_500::valid_value<wchar_t>(wchar_t, long, std::__1::integral_constant<bool, true> const&)
1731
template <class charT>
1732
bool valid_value(charT, std::intmax_t, const std::integral_constant<bool, false>&)
1733
{
1734
   return true; // v will alsways fit in a charT
1735
}
1736
template <class charT>
1737
bool valid_value(charT c, std::intmax_t v)
1738
2.03k
{
1739
2.03k
   return valid_value(c, v, std::integral_constant<bool, (sizeof(charT) < sizeof(std::intmax_t))>());
1740
2.03k
}
bool boost::re_detail_500::valid_value<char>(char, long)
Line
Count
Source
1738
2.03k
{
1739
2.03k
   return valid_value(c, v, std::integral_constant<bool, (sizeof(charT) < sizeof(std::intmax_t))>());
1740
2.03k
}
Unexecuted instantiation: bool boost::re_detail_500::valid_value<wchar_t>(wchar_t, long)
1741
1742
template <class charT, class traits>
1743
charT basic_regex_parser<charT, traits>::unescape_character()
1744
89.1k
{
1745
#ifdef BOOST_REGEX_MSVC
1746
#pragma warning(push)
1747
#pragma warning(disable:4127)
1748
#endif
1749
89.1k
   charT result(0);
1750
89.1k
   if(m_position == m_end)
1751
0
   {
1752
0
      fail(regex_constants::error_escape, m_position - m_base, "Escape sequence terminated prematurely.");
1753
0
      return false;
1754
0
   }
1755
89.1k
   switch(this->m_traits.escape_syntax_type(*m_position))
1756
89.1k
   {
1757
70
   case regex_constants::escape_type_control_a:
1758
70
      result = charT('\a');
1759
70
      break;
1760
0
   case regex_constants::escape_type_e:
1761
0
      result = charT(27);
1762
0
      break;
1763
57
   case regex_constants::escape_type_control_f:
1764
57
      result = charT('\f');
1765
57
      break;
1766
11.4k
   case regex_constants::escape_type_control_n:
1767
11.4k
      result = charT('\n');
1768
11.4k
      break;
1769
3.72k
   case regex_constants::escape_type_control_r:
1770
3.72k
      result = charT('\r');
1771
3.72k
      break;
1772
0
   case regex_constants::escape_type_control_t:
1773
0
      result = charT('\t');
1774
0
      break;
1775
0
   case regex_constants::escape_type_control_v:
1776
0
      result = charT('\v');
1777
0
      break;
1778
1
   case regex_constants::escape_type_word_assert:
1779
1
      result = charT('\b');
1780
1
      break;
1781
150
   case regex_constants::escape_type_ascii_control:
1782
150
      ++m_position;
1783
150
      if(m_position == m_end)
1784
0
      {
1785
         // Rewind to start of escape:
1786
0
         --m_position;
1787
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1788
0
         fail(regex_constants::error_escape, m_position - m_base, "ASCII escape sequence terminated prematurely.");
1789
0
         return result;
1790
0
      }
1791
150
      result = static_cast<charT>(*m_position % 32);
1792
150
      break;
1793
2.06k
   case regex_constants::escape_type_hex:
1794
2.06k
      ++m_position;
1795
2.06k
      if(m_position == m_end)
1796
0
      {
1797
         // Rewind to start of escape:
1798
0
         --m_position;
1799
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1800
0
         fail(regex_constants::error_escape, m_position - m_base, "Hexadecimal escape sequence terminated prematurely.");
1801
0
         return result;
1802
0
      }
1803
      // maybe have \x{ddd}
1804
2.06k
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
1805
32
      {
1806
32
         ++m_position;
1807
32
         if(m_position == m_end)
1808
0
         {
1809
            // Rewind to start of escape:
1810
0
            --m_position;
1811
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1812
0
            fail(regex_constants::error_escape, m_position - m_base, "Missing } in hexadecimal escape sequence.");
1813
0
            return result;
1814
0
         }
1815
32
         std::intmax_t i = this->m_traits.toi(m_position, m_end, 16);
1816
32
         if((m_position == m_end)
1817
32
            || (i < 0)
1818
32
            || ((std::numeric_limits<charT>::is_specialized) && (i > (std::intmax_t)(std::numeric_limits<charT>::max)()))
1819
32
            || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
1820
0
         {
1821
            // Rewind to start of escape:
1822
0
            --m_position;
1823
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1824
0
            fail(regex_constants::error_badbrace, m_position - m_base, "Hexadecimal escape sequence was invalid.");
1825
0
            return result;
1826
0
         }
1827
32
         ++m_position;
1828
32
         result = charT(i);
1829
32
      }
1830
2.03k
      else
1831
2.03k
      {
1832
2.03k
         std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), static_cast<std::ptrdiff_t>(m_end - m_position));
1833
2.03k
         std::intmax_t i = this->m_traits.toi(m_position, m_position + len, 16);
1834
2.03k
         if((i < 0)
1835
2.03k
            || !valid_value(charT(0), i))
1836
0
         {
1837
            // Rewind to start of escape:
1838
0
            --m_position;
1839
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1840
0
            fail(regex_constants::error_escape, m_position - m_base, "Escape sequence did not encode a valid character.");
1841
0
            return result;
1842
0
         }
1843
2.03k
         result = charT(i);
1844
2.03k
      }
1845
2.06k
      return result;
1846
222
   case regex_constants::syntax_digit:
1847
222
      {
1848
      // an octal escape sequence, the first character must be a zero
1849
      // followed by up to 3 octal digits:
1850
222
      std::ptrdiff_t len = (std::min)(std::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
1851
222
      const charT* bp = m_position;
1852
222
      std::intmax_t val = this->m_traits.toi(bp, bp + 1, 8);
1853
222
      if(val != 0)
1854
0
      {
1855
         // Rewind to start of escape:
1856
0
         --m_position;
1857
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1858
         // Oops not an octal escape after all:
1859
0
         fail(regex_constants::error_escape, m_position - m_base, "Invalid octal escape sequence.");
1860
0
         return result;
1861
0
      }
1862
222
      val = this->m_traits.toi(m_position, m_position + len, 8);
1863
222
      if((val < 0) || (val > (std::intmax_t)(std::numeric_limits<charT>::max)()))
1864
0
      {
1865
         // Rewind to start of escape:
1866
0
         --m_position;
1867
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1868
0
         fail(regex_constants::error_escape, m_position - m_base, "Octal escape sequence is invalid.");
1869
0
         return result;
1870
0
      }
1871
222
      return static_cast<charT>(val);
1872
222
      }
1873
1
   case regex_constants::escape_type_named_char:
1874
1
      {
1875
1
         ++m_position;
1876
1
         if(m_position == m_end)
1877
0
         {
1878
            // Rewind to start of escape:
1879
0
            --m_position;
1880
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1881
0
            fail(regex_constants::error_escape, m_position - m_base);
1882
0
            return false;
1883
0
         }
1884
         // maybe have \N{name}
1885
1
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
1886
1
         {
1887
1
            const charT* base = m_position;
1888
            // skip forward until we find enclosing brace:
1889
177
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
1890
176
               ++m_position;
1891
1
            if(m_position == m_end)
1892
1
            {
1893
               // Rewind to start of escape:
1894
1
               --m_position;
1895
178
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1896
1
               fail(regex_constants::error_escape, m_position - m_base);
1897
1
               return false;
1898
1
            }
1899
0
            string_type s = this->m_traits.lookup_collatename(++base, m_position++);
1900
0
            if(s.empty())
1901
0
            {
1902
               // Rewind to start of escape:
1903
0
               --m_position;
1904
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1905
0
               fail(regex_constants::error_collate, m_position - m_base);
1906
0
               return false;
1907
0
            }
1908
0
            if(s.size() == 1)
1909
0
            {
1910
0
               return s[0];
1911
0
            }
1912
0
         }
1913
         // fall through is a failure:
1914
         // Rewind to start of escape:
1915
0
         --m_position;
1916
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1917
0
         fail(regex_constants::error_escape, m_position - m_base);
1918
0
         return false;
1919
1
      }
1920
71.4k
   default:
1921
71.4k
      result = *m_position;
1922
71.4k
      break;
1923
89.1k
   }
1924
86.8k
   ++m_position;
1925
86.8k
   return result;
1926
#ifdef BOOST_REGEX_MSVC
1927
#pragma warning(pop)
1928
#endif
1929
89.1k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::unescape_character()
Line
Count
Source
1744
89.1k
{
1745
#ifdef BOOST_REGEX_MSVC
1746
#pragma warning(push)
1747
#pragma warning(disable:4127)
1748
#endif
1749
89.1k
   charT result(0);
1750
89.1k
   if(m_position == m_end)
1751
0
   {
1752
0
      fail(regex_constants::error_escape, m_position - m_base, "Escape sequence terminated prematurely.");
1753
0
      return false;
1754
0
   }
1755
89.1k
   switch(this->m_traits.escape_syntax_type(*m_position))
1756
89.1k
   {
1757
70
   case regex_constants::escape_type_control_a:
1758
70
      result = charT('\a');
1759
70
      break;
1760
0
   case regex_constants::escape_type_e:
1761
0
      result = charT(27);
1762
0
      break;
1763
57
   case regex_constants::escape_type_control_f:
1764
57
      result = charT('\f');
1765
57
      break;
1766
11.4k
   case regex_constants::escape_type_control_n:
1767
11.4k
      result = charT('\n');
1768
11.4k
      break;
1769
3.72k
   case regex_constants::escape_type_control_r:
1770
3.72k
      result = charT('\r');
1771
3.72k
      break;
1772
0
   case regex_constants::escape_type_control_t:
1773
0
      result = charT('\t');
1774
0
      break;
1775
0
   case regex_constants::escape_type_control_v:
1776
0
      result = charT('\v');
1777
0
      break;
1778
1
   case regex_constants::escape_type_word_assert:
1779
1
      result = charT('\b');
1780
1
      break;
1781
150
   case regex_constants::escape_type_ascii_control:
1782
150
      ++m_position;
1783
150
      if(m_position == m_end)
1784
0
      {
1785
         // Rewind to start of escape:
1786
0
         --m_position;
1787
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1788
0
         fail(regex_constants::error_escape, m_position - m_base, "ASCII escape sequence terminated prematurely.");
1789
0
         return result;
1790
0
      }
1791
150
      result = static_cast<charT>(*m_position % 32);
1792
150
      break;
1793
2.06k
   case regex_constants::escape_type_hex:
1794
2.06k
      ++m_position;
1795
2.06k
      if(m_position == m_end)
1796
0
      {
1797
         // Rewind to start of escape:
1798
0
         --m_position;
1799
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1800
0
         fail(regex_constants::error_escape, m_position - m_base, "Hexadecimal escape sequence terminated prematurely.");
1801
0
         return result;
1802
0
      }
1803
      // maybe have \x{ddd}
1804
2.06k
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
1805
32
      {
1806
32
         ++m_position;
1807
32
         if(m_position == m_end)
1808
0
         {
1809
            // Rewind to start of escape:
1810
0
            --m_position;
1811
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1812
0
            fail(regex_constants::error_escape, m_position - m_base, "Missing } in hexadecimal escape sequence.");
1813
0
            return result;
1814
0
         }
1815
32
         std::intmax_t i = this->m_traits.toi(m_position, m_end, 16);
1816
32
         if((m_position == m_end)
1817
32
            || (i < 0)
1818
32
            || ((std::numeric_limits<charT>::is_specialized) && (i > (std::intmax_t)(std::numeric_limits<charT>::max)()))
1819
32
            || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
1820
0
         {
1821
            // Rewind to start of escape:
1822
0
            --m_position;
1823
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1824
0
            fail(regex_constants::error_badbrace, m_position - m_base, "Hexadecimal escape sequence was invalid.");
1825
0
            return result;
1826
0
         }
1827
32
         ++m_position;
1828
32
         result = charT(i);
1829
32
      }
1830
2.03k
      else
1831
2.03k
      {
1832
2.03k
         std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), static_cast<std::ptrdiff_t>(m_end - m_position));
1833
2.03k
         std::intmax_t i = this->m_traits.toi(m_position, m_position + len, 16);
1834
2.03k
         if((i < 0)
1835
2.03k
            || !valid_value(charT(0), i))
1836
0
         {
1837
            // Rewind to start of escape:
1838
0
            --m_position;
1839
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1840
0
            fail(regex_constants::error_escape, m_position - m_base, "Escape sequence did not encode a valid character.");
1841
0
            return result;
1842
0
         }
1843
2.03k
         result = charT(i);
1844
2.03k
      }
1845
2.06k
      return result;
1846
222
   case regex_constants::syntax_digit:
1847
222
      {
1848
      // an octal escape sequence, the first character must be a zero
1849
      // followed by up to 3 octal digits:
1850
222
      std::ptrdiff_t len = (std::min)(std::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
1851
222
      const charT* bp = m_position;
1852
222
      std::intmax_t val = this->m_traits.toi(bp, bp + 1, 8);
1853
222
      if(val != 0)
1854
0
      {
1855
         // Rewind to start of escape:
1856
0
         --m_position;
1857
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1858
         // Oops not an octal escape after all:
1859
0
         fail(regex_constants::error_escape, m_position - m_base, "Invalid octal escape sequence.");
1860
0
         return result;
1861
0
      }
1862
222
      val = this->m_traits.toi(m_position, m_position + len, 8);
1863
222
      if((val < 0) || (val > (std::intmax_t)(std::numeric_limits<charT>::max)()))
1864
0
      {
1865
         // Rewind to start of escape:
1866
0
         --m_position;
1867
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1868
0
         fail(regex_constants::error_escape, m_position - m_base, "Octal escape sequence is invalid.");
1869
0
         return result;
1870
0
      }
1871
222
      return static_cast<charT>(val);
1872
222
      }
1873
1
   case regex_constants::escape_type_named_char:
1874
1
      {
1875
1
         ++m_position;
1876
1
         if(m_position == m_end)
1877
0
         {
1878
            // Rewind to start of escape:
1879
0
            --m_position;
1880
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1881
0
            fail(regex_constants::error_escape, m_position - m_base);
1882
0
            return false;
1883
0
         }
1884
         // maybe have \N{name}
1885
1
         if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
1886
1
         {
1887
1
            const charT* base = m_position;
1888
            // skip forward until we find enclosing brace:
1889
177
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
1890
176
               ++m_position;
1891
1
            if(m_position == m_end)
1892
1
            {
1893
               // Rewind to start of escape:
1894
1
               --m_position;
1895
178
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1896
1
               fail(regex_constants::error_escape, m_position - m_base);
1897
1
               return false;
1898
1
            }
1899
0
            string_type s = this->m_traits.lookup_collatename(++base, m_position++);
1900
0
            if(s.empty())
1901
0
            {
1902
               // Rewind to start of escape:
1903
0
               --m_position;
1904
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1905
0
               fail(regex_constants::error_collate, m_position - m_base);
1906
0
               return false;
1907
0
            }
1908
0
            if(s.size() == 1)
1909
0
            {
1910
0
               return s[0];
1911
0
            }
1912
0
         }
1913
         // fall through is a failure:
1914
         // Rewind to start of escape:
1915
0
         --m_position;
1916
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1917
0
         fail(regex_constants::error_escape, m_position - m_base);
1918
0
         return false;
1919
1
      }
1920
71.4k
   default:
1921
71.4k
      result = *m_position;
1922
71.4k
      break;
1923
89.1k
   }
1924
86.8k
   ++m_position;
1925
86.8k
   return result;
1926
#ifdef BOOST_REGEX_MSVC
1927
#pragma warning(pop)
1928
#endif
1929
89.1k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::unescape_character()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::unescape_character()
1930
1931
template <class charT, class traits>
1932
bool basic_regex_parser<charT, traits>::parse_backref()
1933
68.6k
{
1934
68.6k
   BOOST_REGEX_ASSERT(m_position != m_end);
1935
68.6k
   const charT* pc = m_position;
1936
68.6k
   std::intmax_t i = this->m_traits.toi(pc, pc + 1, 10);
1937
68.6k
   if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))
1938
222
   {
1939
      // not a backref at all but an octal escape sequence:
1940
222
      charT c = unescape_character();
1941
222
      this->append_literal(c);
1942
222
   }
1943
68.4k
   else if((i > 0))
1944
68.4k
   {
1945
68.4k
      m_position = pc;
1946
68.4k
      re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
1947
68.4k
      pb->index = (int)i;
1948
68.4k
      pb->icase = this->flags() & regbase::icase;
1949
68.4k
      if(i > m_max_backref)
1950
30
         m_max_backref = i;
1951
68.4k
   }
1952
0
   else
1953
0
   {
1954
      // Rewind to start of escape:
1955
0
      --m_position;
1956
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1957
0
      fail(regex_constants::error_backref, m_position - m_base);
1958
0
      return false;
1959
0
   }
1960
68.6k
   return true;
1961
68.6k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_backref()
Line
Count
Source
1933
68.6k
{
1934
68.6k
   BOOST_REGEX_ASSERT(m_position != m_end);
1935
68.6k
   const charT* pc = m_position;
1936
68.6k
   std::intmax_t i = this->m_traits.toi(pc, pc + 1, 10);
1937
68.6k
   if((i == 0) || (((this->flags() & regbase::main_option_type) == regbase::perl_syntax_group) && (this->flags() & regbase::no_bk_refs)))
1938
222
   {
1939
      // not a backref at all but an octal escape sequence:
1940
222
      charT c = unescape_character();
1941
222
      this->append_literal(c);
1942
222
   }
1943
68.4k
   else if((i > 0))
1944
68.4k
   {
1945
68.4k
      m_position = pc;
1946
68.4k
      re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_backref, sizeof(re_brace)));
1947
68.4k
      pb->index = (int)i;
1948
68.4k
      pb->icase = this->flags() & regbase::icase;
1949
68.4k
      if(i > m_max_backref)
1950
30
         m_max_backref = i;
1951
68.4k
   }
1952
0
   else
1953
0
   {
1954
      // Rewind to start of escape:
1955
0
      --m_position;
1956
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape) --m_position;
1957
0
      fail(regex_constants::error_backref, m_position - m_base);
1958
0
      return false;
1959
0
   }
1960
68.6k
   return true;
1961
68.6k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_backref()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_backref()
1962
1963
template <class charT, class traits>
1964
bool basic_regex_parser<charT, traits>::parse_QE()
1965
9.55k
{
1966
#ifdef BOOST_REGEX_MSVC
1967
#pragma warning(push)
1968
#pragma warning(disable:4127)
1969
#endif
1970
   //
1971
   // parse a \Q...\E sequence:
1972
   //
1973
9.55k
   ++m_position; // skip the Q
1974
9.55k
   const charT* start = m_position;
1975
9.55k
   const charT* end;
1976
9.55k
   do
1977
23.3k
   {
1978
1.73M
      while((m_position != m_end) 
1979
1.73M
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))
1980
1.71M
         ++m_position;
1981
23.3k
      if(m_position == m_end)
1982
10
      {
1983
         //  a \Q...\E sequence may terminate with the end of the expression:
1984
10
         end = m_position;
1985
10
         break;  
1986
10
      }
1987
23.3k
      if(++m_position == m_end) // skip the escape
1988
0
      {
1989
0
         fail(regex_constants::error_escape, m_position - m_base, "Unterminated \\Q...\\E sequence.");
1990
0
         return false;
1991
0
      }
1992
      // check to see if it's a \E:
1993
23.3k
      if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)
1994
9.54k
      {
1995
9.54k
         ++m_position;
1996
9.54k
         end = m_position - 2;
1997
9.54k
         break;
1998
9.54k
      }
1999
      // otherwise go round again:
2000
23.3k
   }while(true);
2001
   //
2002
   // now add all the character between the two escapes as literals:
2003
   //
2004
1.73M
   while(start != end)
2005
1.72M
   {
2006
1.72M
      this->append_literal(*start);
2007
1.72M
      ++start;
2008
1.72M
   }
2009
9.55k
   return true;
2010
#ifdef BOOST_REGEX_MSVC
2011
#pragma warning(pop)
2012
#endif
2013
9.55k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_QE()
Line
Count
Source
1965
9.55k
{
1966
#ifdef BOOST_REGEX_MSVC
1967
#pragma warning(push)
1968
#pragma warning(disable:4127)
1969
#endif
1970
   //
1971
   // parse a \Q...\E sequence:
1972
   //
1973
9.55k
   ++m_position; // skip the Q
1974
9.55k
   const charT* start = m_position;
1975
9.55k
   const charT* end;
1976
9.55k
   do
1977
23.3k
   {
1978
1.73M
      while((m_position != m_end) 
1979
1.73M
         && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))
1980
1.71M
         ++m_position;
1981
23.3k
      if(m_position == m_end)
1982
10
      {
1983
         //  a \Q...\E sequence may terminate with the end of the expression:
1984
10
         end = m_position;
1985
10
         break;  
1986
10
      }
1987
23.3k
      if(++m_position == m_end) // skip the escape
1988
0
      {
1989
0
         fail(regex_constants::error_escape, m_position - m_base, "Unterminated \\Q...\\E sequence.");
1990
0
         return false;
1991
0
      }
1992
      // check to see if it's a \E:
1993
23.3k
      if(this->m_traits.escape_syntax_type(*m_position) == regex_constants::escape_type_E)
1994
9.54k
      {
1995
9.54k
         ++m_position;
1996
9.54k
         end = m_position - 2;
1997
9.54k
         break;
1998
9.54k
      }
1999
      // otherwise go round again:
2000
23.3k
   }while(true);
2001
   //
2002
   // now add all the character between the two escapes as literals:
2003
   //
2004
1.73M
   while(start != end)
2005
1.72M
   {
2006
1.72M
      this->append_literal(*start);
2007
1.72M
      ++start;
2008
1.72M
   }
2009
9.55k
   return true;
2010
#ifdef BOOST_REGEX_MSVC
2011
#pragma warning(pop)
2012
#endif
2013
9.55k
}
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<char, boost::c_regex_traits<char> >::parse_QE()
Unexecuted instantiation: boost::re_detail_500::basic_regex_parser<wchar_t, boost::c_regex_traits<wchar_t> >::parse_QE()
2014
2015
template <class charT, class traits>
2016
bool basic_regex_parser<charT, traits>::parse_perl_extension()
2017
81.8k
{
2018
81.8k
   if(++m_position == m_end)
2019
0
   {
2020
      // Rewind to start of (? sequence:
2021
0
      --m_position;
2022
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2023
0
      fail(regex_constants::error_perl_extension, m_position - m_base);
2024
0
      return false;
2025
0
   }
2026
   //
2027
   // treat comments as a special case, as these
2028
   // are the only ones that don't start with a leading
2029
   // startmark state:
2030
   //
2031
81.8k
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)
2032
37
   {
2033
90
      while((m_position != m_end) 
2034
90
         && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
2035
53
      {}
2036
37
      return true;
2037
37
   }
2038
   //
2039
   // backup some state, and prepare the way:
2040
   //
2041
81.7k
   int markid = 0;
2042
81.7k
   std::ptrdiff_t jump_offset = 0;
2043
81.7k
   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
2044
81.7k
   pb->icase = this->flags() & regbase::icase;
2045
81.7k
   std::ptrdiff_t last_paren_start = this->getoffset(pb);
2046
   // back up insertion point for alternations, and set new point:
2047
81.7k
   std::ptrdiff_t last_alt_point = m_alt_insert_point;
2048
81.7k
   this->m_pdata->m_data.align();
2049
81.7k
   m_alt_insert_point = this->m_pdata->m_data.size();
2050
81.7k
   std::ptrdiff_t expected_alt_point = m_alt_insert_point;
2051
81.7k
   bool restore_flags = true;
2052
81.7k
   regex_constants::syntax_option_type old_flags = this->flags();
2053
81.7k
   bool old_case_change = m_has_case_change;
2054
81.7k
   m_has_case_change = false;
2055
81.7k
   charT name_delim;
2056
81.7k
   int mark_reset = m_mark_reset;
2057
81.7k
   int max_mark = m_max_mark;
2058
81.7k
   m_mark_reset = -1;
2059
81.7k
   m_max_mark = m_mark_count;
2060
81.7k
   std::intmax_t v;
2061
   //
2062
   // select the actual extension used:
2063
   //
2064
81.7k
   switch(this->m_traits.syntax_type(*m_position))
2065
81.7k
   {
2066
59
   case regex_constants::syntax_or:
2067
59
      m_mark_reset = m_mark_count;
2068
59
      BOOST_REGEX_FALLTHROUGH;
2069
18.5k
   case regex_constants::syntax_colon:
2070
      //
2071
      // a non-capturing mark:
2072
      //
2073
18.5k
      pb->index = markid = 0;
2074
18.5k
      ++m_position;
2075
18.5k
      break;
2076
148
   case regex_constants::syntax_digit:
2077
148
      {
2078
      //
2079
      // a recursive subexpression:
2080
      //
2081
148
      v = this->m_traits.toi(m_position, m_end, 10);
2082
148
      if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2083
1
      {
2084
         // Rewind to start of (? sequence:
2085
1
         --m_position;
2086
3
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2087
1
         fail(regex_constants::error_perl_extension, m_position - m_base, "The recursive sub-expression refers to an invalid marking group, or is unterminated.");
2088
1
         return false;
2089
1
      }
2090
844
insert_recursion:
2091
844
      pb->index = markid = 0;
2092
844
      re_recurse* pr = static_cast<re_recurse*>(this->append_state(syntax_element_recurse, sizeof(re_recurse)));
2093
844
      pr->alt.i = (std::ptrdiff_t)v;
2094
844
      pr->state_id = 0;
2095
844
      static_cast<re_case*>(
2096
844
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2097
844
            )->icase = this->flags() & regbase::icase;
2098
844
      break;
2099
148
      }
2100
294
   case regex_constants::syntax_plus:
2101
      //
2102
      // A forward-relative recursive subexpression:
2103
      //
2104
294
      ++m_position;
2105
294
      v = this->m_traits.toi(m_position, m_end, 10);
2106
294
      if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2107
0
      {
2108
         // Rewind to start of (? sequence:
2109
0
         --m_position;
2110
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2111
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2112
0
         return false;
2113
0
      }
2114
294
      if ((std::numeric_limits<std::intmax_t>::max)() - m_mark_count < v)
2115
0
      {
2116
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2117
0
         return false;
2118
0
      }
2119
294
      v += m_mark_count;
2120
294
      goto insert_recursion;
2121
836
   case regex_constants::syntax_dash:
2122
      //
2123
      // Possibly a backward-relative recursive subexpression:
2124
      //
2125
836
      ++m_position;
2126
836
      v = this->m_traits.toi(m_position, m_end, 10);
2127
836
      if(v <= 0)
2128
835
      {
2129
835
         --m_position;
2130
         // Oops not a relative recursion at all, but a (?-imsx) group:
2131
835
         goto option_group_jump;
2132
835
      }
2133
1
      v = static_cast<std::intmax_t>(m_mark_count) + 1 - v;
2134
1
      if(v <= 0)
2135
1
      {
2136
         // Rewind to start of (? sequence:
2137
1
         --m_position;
2138
15
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2139
1
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2140
1
         return false;
2141
1
      }
2142
0
      goto insert_recursion;
2143
146
   case regex_constants::syntax_equal:
2144
146
      pb->index = markid = -1;
2145
146
      ++m_position;
2146
146
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2147
146
      this->m_pdata->m_data.align();
2148
146
      m_alt_insert_point = this->m_pdata->m_data.size();
2149
146
      break;
2150
67
   case regex_constants::syntax_not:
2151
67
      pb->index = markid = -2;
2152
67
      ++m_position;
2153
67
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2154
67
      this->m_pdata->m_data.align();
2155
67
      m_alt_insert_point = this->m_pdata->m_data.size();
2156
67
      break;
2157
306
   case regex_constants::escape_type_left_word:
2158
306
      {
2159
         // a lookbehind assertion:
2160
306
         if(++m_position == m_end)
2161
0
         {
2162
            // Rewind to start of (? sequence:
2163
0
            --m_position;
2164
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2165
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2166
0
            return false;
2167
0
         }
2168
306
         regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);
2169
306
         if(t == regex_constants::syntax_not)
2170
16
            pb->index = markid = -2;
2171
290
         else if(t == regex_constants::syntax_equal)
2172
247
            pb->index = markid = -1;
2173
43
         else
2174
43
         {
2175
            // Probably a named capture which also starts (?< :
2176
43
            name_delim = '>';
2177
43
            --m_position;
2178
43
            goto named_capture_jump;
2179
43
         }
2180
263
         ++m_position;
2181
263
         jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2182
263
         this->append_state(syntax_element_backstep, sizeof(re_brace));
2183
263
         this->m_pdata->m_data.align();
2184
263
         m_alt_insert_point = this->m_pdata->m_data.size();
2185
263
         break;
2186
306
      }
2187
787
   case regex_constants::escape_type_right_word:
2188
      //
2189
      // an independent sub-expression:
2190
      //
2191
787
      pb->index = markid = -3;
2192
787
      ++m_position;
2193
787
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2194
787
      this->m_pdata->m_data.align();
2195
787
      m_alt_insert_point = this->m_pdata->m_data.size();
2196
787
      break;
2197
6.01k
   case regex_constants::syntax_open_mark:
2198
6.01k
      {
2199
      // a conditional expression:
2200
6.01k
      pb->index = markid = -4;
2201
6.01k
      if(++m_position == m_end)
2202
1
      {
2203
         // Rewind to start of (? sequence:
2204
1
         --m_position;
2205
1
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2206
1
         fail(regex_constants::error_perl_extension, m_position - m_base);
2207
1
         return false;
2208
1
      }
2209
6.01k
      v = this->m_traits.toi(m_position, m_end, 10);
2210
6.01k
      if(m_position == m_end)
2211
0
      {
2212
         // Rewind to start of (? sequence:
2213
0
         --m_position;
2214
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2215
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2216
0
         return false;
2217
0
      }
2218
6.01k
      if(*m_position == charT('R'))
2219
745
      {
2220
745
         if(++m_position == m_end)
2221
0
         {
2222
            // Rewind to start of (? sequence:
2223
0
            --m_position;
2224
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2225
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2226
0
            return false;
2227
0
         }
2228
745
         if(*m_position == charT('&'))
2229
583
         {
2230
583
            const charT* base = ++m_position;
2231
277k
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2232
277k
               ++m_position;
2233
583
            if(m_position == m_end)
2234
0
            {
2235
               // Rewind to start of (? sequence:
2236
0
               --m_position;
2237
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2238
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2239
0
               return false;
2240
0
            }
2241
583
            v = -static_cast<int>(hash_value_from_capture_name(base, m_position));
2242
583
         }
2243
162
         else
2244
162
         {
2245
162
            v = -this->m_traits.toi(m_position, m_end, 10);
2246
162
         }
2247
745
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2248
745
         br->index = v < 0 ? (int)(v - 1) : 0;
2249
745
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2250
3
         {
2251
            // Rewind to start of (? sequence:
2252
3
            --m_position;
2253
38
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2254
3
            fail(regex_constants::error_perl_extension, m_position - m_base);
2255
3
            return false;
2256
3
         }
2257
742
         if(++m_position == m_end)
2258
2
         {
2259
            // Rewind to start of (? sequence:
2260
2
            --m_position;
2261
8
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2262
2
            fail(regex_constants::error_perl_extension, m_position - m_base);
2263
2
            return false;
2264
2
         }
2265
742
      }
2266
5.26k
      else if((*m_position == charT('\'')) || (*m_position == charT('<')))
2267
5.04k
      {
2268
5.04k
         const charT* base = ++m_position;
2269
79.6k
         while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\'')))
2270
74.5k
            ++m_position;
2271
5.04k
         if(m_position == m_end)
2272
0
         {
2273
            // Rewind to start of (? sequence:
2274
0
            --m_position;
2275
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2276
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2277
0
            return false;
2278
0
         }
2279
5.04k
         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2280
5.04k
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2281
5.04k
         br->index = (int)v;
2282
5.04k
         if(((*m_position != charT('>')) && (*m_position != charT('\''))) || (++m_position == m_end))
2283
0
         {
2284
            // Rewind to start of (? sequence:
2285
0
            --m_position;
2286
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2287
0
            fail(regex_constants::error_perl_extension, m_position - m_base, "Unterminated named capture.");
2288
0
            return false;
2289
0
         }
2290
5.04k
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2291
2
         {
2292
            // Rewind to start of (? sequence:
2293
2
            --m_position;
2294
13
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2295
2
            fail(regex_constants::error_perl_extension, m_position - m_base);
2296
2
            return false;
2297
2
         }
2298
5.04k
         if(++m_position == m_end)
2299
0
         {
2300
            // Rewind to start of (? sequence:
2301
0
            --m_position;
2302
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2303
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2304
0
            return false;
2305
0
         }
2306
5.04k
      }
2307
222
      else if(*m_position == charT('D'))
2308
0
      {
2309
0
         const char* def = "DEFINE";
2310
0
         while(*def && (m_position != m_end) && (*m_position == charT(*def)))
2311
0
            ++m_position, ++def;
2312
0
         if((m_position == m_end) || *def)
2313
0
         {
2314
            // Rewind to start of (? sequence:
2315
0
            --m_position;
2316
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2317
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2318
0
            return false;
2319
0
         }
2320
0
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2321
0
         br->index = 9999; // special magic value!
2322
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2323
0
         {
2324
            // Rewind to start of (? sequence:
2325
0
            --m_position;
2326
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2327
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2328
0
            return false;
2329
0
         }
2330
0
         if(++m_position == m_end)
2331
0
         {
2332
            // Rewind to start of (? sequence:
2333
0
            --m_position;
2334
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2335
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2336
0
            return false;
2337
0
         }
2338
0
      }
2339
222
      else if(v > 0)
2340
38
      {
2341
38
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2342
38
         br->index = (int)v;
2343
38
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2344
0
         {
2345
            // Rewind to start of (? sequence:
2346
0
            --m_position;
2347
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2348
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2349
0
            return false;
2350
0
         }
2351
38
         if(++m_position == m_end)
2352
0
         {
2353
            // Rewind to start of (? sequence:
2354
0
            --m_position;
2355
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2356
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2357
0
            return false;
2358
0
         }
2359
38
      }
2360
184
      else
2361
184
      {
2362
         // verify that we have a lookahead or lookbehind assert:
2363
184
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)
2364
1
         {
2365
            // Rewind to start of (? sequence:
2366
1
            --m_position;
2367
1
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2368
1
            fail(regex_constants::error_perl_extension, m_position - m_base);
2369
1
            return false;
2370
1
         }
2371
183
         if(++m_position == m_end)
2372
0
         {
2373
            // Rewind to start of (? sequence:
2374
0
            --m_position;
2375
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2376
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2377
0
            return false;
2378
0
         }
2379
183
         if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)
2380
21
         {
2381
21
            if(++m_position == m_end)
2382
0
            {
2383
               // Rewind to start of (? sequence:
2384
0
               --m_position;
2385
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2386
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2387
0
               return false;
2388
0
            }
2389
21
            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
2390
21
               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
2391
1
            {
2392
               // Rewind to start of (? sequence:
2393
1
               --m_position;
2394
3
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2395
1
               fail(regex_constants::error_perl_extension, m_position - m_base);
2396
1
               return false;
2397
1
            }
2398
20
            m_position -= 3;
2399
20
         }
2400
162
         else
2401
162
         {
2402
162
            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
2403
162
               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
2404
1
            {
2405
               // Rewind to start of (? sequence:
2406
1
               --m_position;
2407
2
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2408
1
               fail(regex_constants::error_perl_extension, m_position - m_base);
2409
1
               return false;
2410
1
            }
2411
161
            m_position -= 2;
2412
161
         }
2413
183
      }
2414
6.00k
      break;
2415
6.01k
      }
2416
6.00k
   case regex_constants::syntax_close_mark:
2417
      // Rewind to start of (? sequence:
2418
1
      --m_position;
2419
2
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2420
1
      fail(regex_constants::error_perl_extension, m_position - m_base);
2421
1
      return false;
2422
35.6k
   case regex_constants::escape_type_end_buffer:
2423
35.6k
      {
2424
35.6k
      name_delim = *m_position;
2425
35.6k
named_capture_jump:
2426
35.6k
      markid = 0;
2427
35.6k
      if(0 == (this->flags() & regbase::nosubs))
2428
35.6k
      {
2429
35.6k
         markid = ++m_mark_count;
2430
35.6k
         if(this->flags() & regbase::save_subexpression_location)
2431
0
            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));
2432
35.6k
      }
2433
35.6k
      pb->index = markid;
2434
35.6k
      const charT* base = ++m_position;
2435
35.6k
      if(m_position == m_end)
2436
0
      {
2437
         // Rewind to start of (? sequence:
2438
0
         --m_position;
2439
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2440
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2441
0
         return false;
2442
0
      }
2443
1.26M
      while((m_position != m_end) && (*m_position != name_delim))
2444
1.22M
         ++m_position;
2445
35.6k
      if(m_position == m_end)
2446
1
      {
2447
         // Rewind to start of (? sequence:
2448
1
         --m_position;
2449
139
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2450
1
         fail(regex_constants::error_perl_extension, m_position - m_base);
2451
1
         return false;
2452
1
      }
2453
35.6k
      this->m_pdata->set_name(base, m_position, markid);
2454
35.6k
      ++m_position;
2455
35.6k
      break;
2456
35.6k
      }
2457
18.9k
   default:
2458
18.9k
      if(*m_position == charT('R'))
2459
1
      {
2460
1
         ++m_position;
2461
1
         v = 0;
2462
1
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2463
0
         {
2464
            // Rewind to start of (? sequence:
2465
0
            --m_position;
2466
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2467
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2468
0
            return false;
2469
0
         }
2470
1
         goto insert_recursion;
2471
1
      }
2472
18.9k
      if(*m_position == charT('&'))
2473
369
      {
2474
369
         ++m_position;
2475
369
         const charT* base = m_position;
2476
6.85k
         while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2477
6.48k
            ++m_position;
2478
369
         if(m_position == m_end)
2479
0
         {
2480
            // Rewind to start of (? sequence:
2481
0
            --m_position;
2482
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2483
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2484
0
            return false;
2485
0
         }
2486
369
         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2487
369
         goto insert_recursion;
2488
369
      }
2489
18.6k
      if(*m_position == charT('P'))
2490
34
      {
2491
34
         ++m_position;
2492
34
         if(m_position == m_end)
2493
0
         {
2494
            // Rewind to start of (? sequence:
2495
0
            --m_position;
2496
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2497
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2498
0
            return false;
2499
0
         }
2500
34
         if(*m_position == charT('>'))
2501
34
         {
2502
34
            ++m_position;
2503
34
            const charT* base = m_position;
2504
225
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2505
191
               ++m_position;
2506
34
            if(m_position == m_end)
2507
1
            {
2508
               // Rewind to start of (? sequence:
2509
1
               --m_position;
2510
172
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2511
1
               fail(regex_constants::error_perl_extension, m_position - m_base);
2512
1
               return false;
2513
1
            }
2514
33
            v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2515
33
            goto insert_recursion;
2516
34
         }
2517
34
      }
2518
      //
2519
      // lets assume that we have a (?imsx) group and try and parse it:
2520
      //
2521
19.4k
option_group_jump:
2522
19.4k
      regex_constants::syntax_option_type opts = parse_options();
2523
19.4k
      if(m_position == m_end)
2524
0
      {
2525
         // Rewind to start of (? sequence:
2526
0
         --m_position;
2527
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2528
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2529
0
         return false;
2530
0
      }
2531
      // make a note of whether we have a case change:
2532
19.4k
      m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
2533
19.4k
      pb->index = markid = 0;
2534
19.4k
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)
2535
18.5k
      {
2536
         // update flags and carry on as normal:
2537
18.5k
         this->flags(opts);
2538
18.5k
         restore_flags = false;
2539
18.5k
         old_case_change |= m_has_case_change; // defer end of scope by one ')'
2540
18.5k
      }
2541
832
      else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)
2542
824
      {
2543
         // update flags and carry on until the matching ')' is found:
2544
824
         this->flags(opts);
2545
824
         ++m_position;
2546
824
      }
2547
8
      else
2548
8
      {
2549
         // Rewind to start of (? sequence:
2550
8
         --m_position;
2551
15
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2552
8
         fail(regex_constants::error_perl_extension, m_position - m_base);
2553
8
         return false;
2554
8
      }
2555
2556
      // finally append a case change state if we need it:
2557
19.4k
      if(m_has_case_change)
2558
13.8k
      {
2559
13.8k
         static_cast<re_case*>(
2560
13.8k
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2561
13.8k
            )->icase = opts & regbase::icase;
2562
13.8k
      }
2563
2564
81.7k
   }
2565
   //
2566
   // now recursively add more states, this will terminate when we get to a
2567
   // matching ')' :
2568
   //
2569
81.7k
   parse_all();
2570
   //
2571
   // Unwind alternatives:
2572
   //
2573
81.7k
   if(0 == unwind_alts(last_paren_start))
2574
0
   {
2575
      // Rewind to start of (? sequence:
2576
0
      --m_position;
2577
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2578
0
      fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid alternation operators within (?...) block.");
2579
0
      return false;
2580
0
   }
2581
   //
2582
   // we either have a ')' or we have run out of characters prematurely:
2583
   //
2584
81.7k
   if(m_position == m_end)
2585
12
   {
2586
      // Rewind to start of (? sequence:
2587
12
      --m_position;
2588
18.4k
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2589
12
      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
2590
12
      return false;
2591
12
   }
2592
81.7k
   BOOST_REGEX_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
2593
81.5k
   ++m_position;
2594
   //
2595
   // restore the flags:
2596
   //
2597
81.5k
   if(restore_flags)
2598
62.9k
   {
2599
      // append a case change state if we need it:
2600
62.9k
      if(m_has_case_change)
2601
38
      {
2602
38
         static_cast<re_case*>(
2603
38
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2604
38
            )->icase = old_flags & regbase::icase;
2605
38
      }
2606
62.9k
      this->flags(old_flags);
2607
62.9k
   }
2608
   //
2609
   // set up the jump pointer if we have one:
2610
   //
2611
81.5k
   if(jump_offset)
2612
1.21k
   {
2613
1.21k
      this->m_pdata->m_data.align();
2614
1.21k
      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
2615
1.21k
      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
2616
1.21k
      if((this->m_last_state == jmp) && (markid != -2))
2617
0
      {
2618
         // Oops... we didn't have anything inside the assertion.
2619
         // Note we don't get here for negated forward lookahead as (?!)
2620
         // does have some uses.
2621
         // Rewind to start of (? sequence:
2622
0
         --m_position;
2623
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2624
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid or empty zero width assertion.");
2625
0
         return false;
2626
0
      }
2627
1.21k
   }
2628
   //
2629
   // verify that if this is conditional expression, that we do have
2630
   // an alternative, if not add one:
2631
   //
2632
81.5k
   if(markid == -4)
2633
5.90k
   {
2634
5.90k
      re_syntax_base* b = this->getaddress(expected_alt_point);
2635
      // Make sure we have exactly one alternative following this state:
2636
5.90k
      if(b->type != syntax_element_alt)
2637
5.42k
      {
2638
5.42k
         re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));
2639
5.42k
         alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);
2640
5.42k
      }
2641
476
      else if(((std::ptrdiff_t)this->m_pdata->m_data.size() > (static_cast<re_alt*>(b)->alt.i + this->getoffset(b))) && (static_cast<re_alt*>(b)->alt.i > 0) && this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)
2642
3
      {
2643
         // Can't have seen more than one alternative:
2644
         // Rewind to start of (? sequence:
2645
3
         --m_position;
2646
4.80k
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2647
3
         fail(regex_constants::error_bad_pattern, m_position - m_base, "More than one alternation operator | was encountered inside a conditional expression.");
2648
3
         return false;
2649
3
      }
2650
473
      else
2651
473
      {
2652
         // We must *not* have seen an alternative inside a (DEFINE) block:
2653
473
         b = this->getaddress(b->next.i, b);
2654
473
         if((b->type == syntax_element_assert_backref) && (static_cast<re_brace*>(b)->index == 9999))
2655
0
         {
2656
            // Rewind to start of (? sequence:
2657
0
            --m_position;
2658
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2659
0
            fail(regex_constants::error_bad_pattern, m_position - m_base, "Alternation operators are not allowed inside a DEFINE block.");
2660
0
            return false;
2661
0
         }
2662
473
      }
2663
      // check for invalid repetition of next state:
2664
5.90k
      b = this->getaddress(expected_alt_point);
2665
5.90k
      b = this->getaddress(static_cast<re_alt*>(b)->next.i, b);
2666
5.90k
      if((b->type != syntax_element_assert_backref)
2667
5.90k
         && (b->type != syntax_element_startmark))
2668
9
      {
2669
         // Rewind to start of (? sequence:
2670
9
         --m_position;
2671
655
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2672
9
         fail(regex_constants::error_badrepeat, m_position - m_base, "A repetition operator cannot be applied to a zero-width assertion.");
2673
9
         return false;
2674
9
      }
2675
5.90k
   }
2676
   //
2677
   // append closing parenthesis state:
2678
   //
2679
81.5k
   pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
2680
81.5k
   pb->index = markid;
2681
81.5k
   pb->icase = this->flags() & regbase::icase;
2682
81.5k
   this->m_paren_start = last_paren_start;
2683
   //
2684
   // restore the alternate insertion point:
2685
   //
2686
81.5k
   this->m_alt_insert_point = last_alt_point;
2687
   //
2688
   // and the case change data:
2689
   //
2690
81.5k
   m_has_case_change = old_case_change;
2691
   //
2692
   // And the mark_reset data:
2693
   //
2694
81.5k
   if(m_max_mark > m_mark_count)
2695
39
   {
2696
39
      m_mark_count = m_max_mark;
2697
39
   }
2698
81.5k
   m_mark_reset = mark_reset;
2699
81.5k
   m_max_mark = max_mark;
2700
2701
2702
81.5k
   if(markid > 0)
2703
35.5k
   {
2704
35.5k
      if(this->flags() & regbase::save_subexpression_location)
2705
0
         this->m_pdata->m_subs.at((std::size_t)markid - 1).second = std::distance(m_base, m_position) - 1;
2706
35.5k
   }
2707
81.5k
   return true;
2708
81.5k
}
boost::re_detail_500::basic_regex_parser<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::parse_perl_extension()
Line
Count
Source
2017
81.8k
{
2018
81.8k
   if(++m_position == m_end)
2019
0
   {
2020
      // Rewind to start of (? sequence:
2021
0
      --m_position;
2022
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2023
0
      fail(regex_constants::error_perl_extension, m_position - m_base);
2024
0
      return false;
2025
0
   }
2026
   //
2027
   // treat comments as a special case, as these
2028
   // are the only ones that don't start with a leading
2029
   // startmark state:
2030
   //
2031
81.8k
   if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)
2032
37
   {
2033
90
      while((m_position != m_end) 
2034
90
         && (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
2035
53
      {}
2036
37
      return true;
2037
37
   }
2038
   //
2039
   // backup some state, and prepare the way:
2040
   //
2041
81.7k
   int markid = 0;
2042
81.7k
   std::ptrdiff_t jump_offset = 0;
2043
81.7k
   re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
2044
81.7k
   pb->icase = this->flags() & regbase::icase;
2045
81.7k
   std::ptrdiff_t last_paren_start = this->getoffset(pb);
2046
   // back up insertion point for alternations, and set new point:
2047
81.7k
   std::ptrdiff_t last_alt_point = m_alt_insert_point;
2048
81.7k
   this->m_pdata->m_data.align();
2049
81.7k
   m_alt_insert_point = this->m_pdata->m_data.size();
2050
81.7k
   std::ptrdiff_t expected_alt_point = m_alt_insert_point;
2051
81.7k
   bool restore_flags = true;
2052
81.7k
   regex_constants::syntax_option_type old_flags = this->flags();
2053
81.7k
   bool old_case_change = m_has_case_change;
2054
81.7k
   m_has_case_change = false;
2055
81.7k
   charT name_delim;
2056
81.7k
   int mark_reset = m_mark_reset;
2057
81.7k
   int max_mark = m_max_mark;
2058
81.7k
   m_mark_reset = -1;
2059
81.7k
   m_max_mark = m_mark_count;
2060
81.7k
   std::intmax_t v;
2061
   //
2062
   // select the actual extension used:
2063
   //
2064
81.7k
   switch(this->m_traits.syntax_type(*m_position))
2065
81.7k
   {
2066
59
   case regex_constants::syntax_or:
2067
59
      m_mark_reset = m_mark_count;
2068
59
      BOOST_REGEX_FALLTHROUGH;
2069
18.5k
   case regex_constants::syntax_colon:
2070
      //
2071
      // a non-capturing mark:
2072
      //
2073
18.5k
      pb->index = markid = 0;
2074
18.5k
      ++m_position;
2075
18.5k
      break;
2076
148
   case regex_constants::syntax_digit:
2077
148
      {
2078
      //
2079
      // a recursive subexpression:
2080
      //
2081
148
      v = this->m_traits.toi(m_position, m_end, 10);
2082
148
      if((v < 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2083
1
      {
2084
         // Rewind to start of (? sequence:
2085
1
         --m_position;
2086
3
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2087
1
         fail(regex_constants::error_perl_extension, m_position - m_base, "The recursive sub-expression refers to an invalid marking group, or is unterminated.");
2088
1
         return false;
2089
1
      }
2090
844
insert_recursion:
2091
844
      pb->index = markid = 0;
2092
844
      re_recurse* pr = static_cast<re_recurse*>(this->append_state(syntax_element_recurse, sizeof(re_recurse)));
2093
844
      pr->alt.i = (std::ptrdiff_t)v;
2094
844
      pr->state_id = 0;
2095
844
      static_cast<re_case*>(
2096
844
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2097
844
            )->icase = this->flags() & regbase::icase;
2098
844
      break;
2099
148
      }
2100
294
   case regex_constants::syntax_plus:
2101
      //
2102
      // A forward-relative recursive subexpression:
2103
      //
2104
294
      ++m_position;
2105
294
      v = this->m_traits.toi(m_position, m_end, 10);
2106
294
      if((v <= 0) || (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2107
0
      {
2108
         // Rewind to start of (? sequence:
2109
0
         --m_position;
2110
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2111
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2112
0
         return false;
2113
0
      }
2114
294
      if ((std::numeric_limits<std::intmax_t>::max)() - m_mark_count < v)
2115
0
      {
2116
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2117
0
         return false;
2118
0
      }
2119
294
      v += m_mark_count;
2120
294
      goto insert_recursion;
2121
836
   case regex_constants::syntax_dash:
2122
      //
2123
      // Possibly a backward-relative recursive subexpression:
2124
      //
2125
836
      ++m_position;
2126
836
      v = this->m_traits.toi(m_position, m_end, 10);
2127
836
      if(v <= 0)
2128
835
      {
2129
835
         --m_position;
2130
         // Oops not a relative recursion at all, but a (?-imsx) group:
2131
835
         goto option_group_jump;
2132
835
      }
2133
1
      v = static_cast<std::intmax_t>(m_mark_count) + 1 - v;
2134
1
      if(v <= 0)
2135
1
      {
2136
         // Rewind to start of (? sequence:
2137
1
         --m_position;
2138
15
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2139
1
         fail(regex_constants::error_perl_extension, m_position - m_base, "An invalid or unterminated recursive sub-expression.");
2140
1
         return false;
2141
1
      }
2142
0
      goto insert_recursion;
2143
146
   case regex_constants::syntax_equal:
2144
146
      pb->index = markid = -1;
2145
146
      ++m_position;
2146
146
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2147
146
      this->m_pdata->m_data.align();
2148
146
      m_alt_insert_point = this->m_pdata->m_data.size();
2149
146
      break;
2150
67
   case regex_constants::syntax_not:
2151
67
      pb->index = markid = -2;
2152
67
      ++m_position;
2153
67
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2154
67
      this->m_pdata->m_data.align();
2155
67
      m_alt_insert_point = this->m_pdata->m_data.size();
2156
67
      break;
2157
306
   case regex_constants::escape_type_left_word:
2158
306
      {
2159
         // a lookbehind assertion:
2160
306
         if(++m_position == m_end)
2161
0
         {
2162
            // Rewind to start of (? sequence:
2163
0
            --m_position;
2164
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2165
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2166
0
            return false;
2167
0
         }
2168
306
         regex_constants::syntax_type t = this->m_traits.syntax_type(*m_position);
2169
306
         if(t == regex_constants::syntax_not)
2170
16
            pb->index = markid = -2;
2171
290
         else if(t == regex_constants::syntax_equal)
2172
247
            pb->index = markid = -1;
2173
43
         else
2174
43
         {
2175
            // Probably a named capture which also starts (?< :
2176
43
            name_delim = '>';
2177
43
            --m_position;
2178
43
            goto named_capture_jump;
2179
43
         }
2180
263
         ++m_position;
2181
263
         jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2182
263
         this->append_state(syntax_element_backstep, sizeof(re_brace));
2183
263
         this->m_pdata->m_data.align();
2184
263
         m_alt_insert_point = this->m_pdata->m_data.size();
2185
263
         break;
2186
306
      }
2187
787
   case regex_constants::escape_type_right_word:
2188
      //
2189
      // an independent sub-expression:
2190
      //
2191
787
      pb->index = markid = -3;
2192
787
      ++m_position;
2193
787
      jump_offset = this->getoffset(this->append_state(syntax_element_jump, sizeof(re_jump)));
2194
787
      this->m_pdata->m_data.align();
2195
787
      m_alt_insert_point = this->m_pdata->m_data.size();
2196
787
      break;
2197
6.01k
   case regex_constants::syntax_open_mark:
2198
6.01k
      {
2199
      // a conditional expression:
2200
6.01k
      pb->index = markid = -4;
2201
6.01k
      if(++m_position == m_end)
2202
1
      {
2203
         // Rewind to start of (? sequence:
2204
1
         --m_position;
2205
1
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2206
1
         fail(regex_constants::error_perl_extension, m_position - m_base);
2207
1
         return false;
2208
1
      }
2209
6.01k
      v = this->m_traits.toi(m_position, m_end, 10);
2210
6.01k
      if(m_position == m_end)
2211
0
      {
2212
         // Rewind to start of (? sequence:
2213
0
         --m_position;
2214
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2215
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2216
0
         return false;
2217
0
      }
2218
6.01k
      if(*m_position == charT('R'))
2219
745
      {
2220
745
         if(++m_position == m_end)
2221
0
         {
2222
            // Rewind to start of (? sequence:
2223
0
            --m_position;
2224
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2225
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2226
0
            return false;
2227
0
         }
2228
745
         if(*m_position == charT('&'))
2229
583
         {
2230
583
            const charT* base = ++m_position;
2231
277k
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2232
277k
               ++m_position;
2233
583
            if(m_position == m_end)
2234
0
            {
2235
               // Rewind to start of (? sequence:
2236
0
               --m_position;
2237
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2238
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2239
0
               return false;
2240
0
            }
2241
583
            v = -static_cast<int>(hash_value_from_capture_name(base, m_position));
2242
583
         }
2243
162
         else
2244
162
         {
2245
162
            v = -this->m_traits.toi(m_position, m_end, 10);
2246
162
         }
2247
745
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2248
745
         br->index = v < 0 ? (int)(v - 1) : 0;
2249
745
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2250
3
         {
2251
            // Rewind to start of (? sequence:
2252
3
            --m_position;
2253
38
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2254
3
            fail(regex_constants::error_perl_extension, m_position - m_base);
2255
3
            return false;
2256
3
         }
2257
742
         if(++m_position == m_end)
2258
2
         {
2259
            // Rewind to start of (? sequence:
2260
2
            --m_position;
2261
8
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2262
2
            fail(regex_constants::error_perl_extension, m_position - m_base);
2263
2
            return false;
2264
2
         }
2265
742
      }
2266
5.26k
      else if((*m_position == charT('\'')) || (*m_position == charT('<')))
2267
5.04k
      {
2268
5.04k
         const charT* base = ++m_position;
2269
79.6k
         while((m_position != m_end) && (*m_position != charT('>')) && (*m_position != charT('\'')))
2270
74.5k
            ++m_position;
2271
5.04k
         if(m_position == m_end)
2272
0
         {
2273
            // Rewind to start of (? sequence:
2274
0
            --m_position;
2275
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2276
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2277
0
            return false;
2278
0
         }
2279
5.04k
         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2280
5.04k
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2281
5.04k
         br->index = (int)v;
2282
5.04k
         if(((*m_position != charT('>')) && (*m_position != charT('\''))) || (++m_position == m_end))
2283
0
         {
2284
            // Rewind to start of (? sequence:
2285
0
            --m_position;
2286
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2287
0
            fail(regex_constants::error_perl_extension, m_position - m_base, "Unterminated named capture.");
2288
0
            return false;
2289
0
         }
2290
5.04k
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2291
2
         {
2292
            // Rewind to start of (? sequence:
2293
2
            --m_position;
2294
13
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2295
2
            fail(regex_constants::error_perl_extension, m_position - m_base);
2296
2
            return false;
2297
2
         }
2298
5.04k
         if(++m_position == m_end)
2299
0
         {
2300
            // Rewind to start of (? sequence:
2301
0
            --m_position;
2302
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2303
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2304
0
            return false;
2305
0
         }
2306
5.04k
      }
2307
222
      else if(*m_position == charT('D'))
2308
0
      {
2309
0
         const char* def = "DEFINE";
2310
0
         while(*def && (m_position != m_end) && (*m_position == charT(*def)))
2311
0
            ++m_position, ++def;
2312
0
         if((m_position == m_end) || *def)
2313
0
         {
2314
            // Rewind to start of (? sequence:
2315
0
            --m_position;
2316
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2317
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2318
0
            return false;
2319
0
         }
2320
0
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2321
0
         br->index = 9999; // special magic value!
2322
0
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2323
0
         {
2324
            // Rewind to start of (? sequence:
2325
0
            --m_position;
2326
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2327
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2328
0
            return false;
2329
0
         }
2330
0
         if(++m_position == m_end)
2331
0
         {
2332
            // Rewind to start of (? sequence:
2333
0
            --m_position;
2334
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2335
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2336
0
            return false;
2337
0
         }
2338
0
      }
2339
222
      else if(v > 0)
2340
38
      {
2341
38
         re_brace* br = static_cast<re_brace*>(this->append_state(syntax_element_assert_backref, sizeof(re_brace)));
2342
38
         br->index = (int)v;
2343
38
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2344
0
         {
2345
            // Rewind to start of (? sequence:
2346
0
            --m_position;
2347
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2348
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2349
0
            return false;
2350
0
         }
2351
38
         if(++m_position == m_end)
2352
0
         {
2353
            // Rewind to start of (? sequence:
2354
0
            --m_position;
2355
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2356
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2357
0
            return false;
2358
0
         }
2359
38
      }
2360
184
      else
2361
184
      {
2362
         // verify that we have a lookahead or lookbehind assert:
2363
184
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_question)
2364
1
         {
2365
            // Rewind to start of (? sequence:
2366
1
            --m_position;
2367
1
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2368
1
            fail(regex_constants::error_perl_extension, m_position - m_base);
2369
1
            return false;
2370
1
         }
2371
183
         if(++m_position == m_end)
2372
0
         {
2373
            // Rewind to start of (? sequence:
2374
0
            --m_position;
2375
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2376
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2377
0
            return false;
2378
0
         }
2379
183
         if(this->m_traits.syntax_type(*m_position) == regex_constants::escape_type_left_word)
2380
21
         {
2381
21
            if(++m_position == m_end)
2382
0
            {
2383
               // Rewind to start of (? sequence:
2384
0
               --m_position;
2385
0
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2386
0
               fail(regex_constants::error_perl_extension, m_position - m_base);
2387
0
               return false;
2388
0
            }
2389
21
            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
2390
21
               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
2391
1
            {
2392
               // Rewind to start of (? sequence:
2393
1
               --m_position;
2394
3
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2395
1
               fail(regex_constants::error_perl_extension, m_position - m_base);
2396
1
               return false;
2397
1
            }
2398
20
            m_position -= 3;
2399
20
         }
2400
162
         else
2401
162
         {
2402
162
            if((this->m_traits.syntax_type(*m_position) != regex_constants::syntax_equal)
2403
162
               && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_not))
2404
1
            {
2405
               // Rewind to start of (? sequence:
2406
1
               --m_position;
2407
2
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2408
1
               fail(regex_constants::error_perl_extension, m_position - m_base);
2409
1
               return false;
2410
1
            }
2411
161
            m_position -= 2;
2412
161
         }
2413
183
      }
2414
6.00k
      break;
2415
6.01k
      }
2416
6.00k
   case regex_constants::syntax_close_mark:
2417
      // Rewind to start of (? sequence:
2418
1
      --m_position;
2419
2
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2420
1
      fail(regex_constants::error_perl_extension, m_position - m_base);
2421
1
      return false;
2422
35.6k
   case regex_constants::escape_type_end_buffer:
2423
35.6k
      {
2424
35.6k
      name_delim = *m_position;
2425
35.6k
named_capture_jump:
2426
35.6k
      markid = 0;
2427
35.6k
      if(0 == (this->flags() & regbase::nosubs))
2428
35.6k
      {
2429
35.6k
         markid = ++m_mark_count;
2430
35.6k
         if(this->flags() & regbase::save_subexpression_location)
2431
0
            this->m_pdata->m_subs.push_back(std::pair<std::size_t, std::size_t>(std::distance(m_base, m_position) - 2, 0));
2432
35.6k
      }
2433
35.6k
      pb->index = markid;
2434
35.6k
      const charT* base = ++m_position;
2435
35.6k
      if(m_position == m_end)
2436
0
      {
2437
         // Rewind to start of (? sequence:
2438
0
         --m_position;
2439
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2440
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2441
0
         return false;
2442
0
      }
2443
1.26M
      while((m_position != m_end) && (*m_position != name_delim))
2444
1.22M
         ++m_position;
2445
35.6k
      if(m_position == m_end)
2446
1
      {
2447
         // Rewind to start of (? sequence:
2448
1
         --m_position;
2449
139
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2450
1
         fail(regex_constants::error_perl_extension, m_position - m_base);
2451
1
         return false;
2452
1
      }
2453
35.6k
      this->m_pdata->set_name(base, m_position, markid);
2454
35.6k
      ++m_position;
2455
35.6k
      break;
2456
35.6k
      }
2457
18.9k
   default:
2458
18.9k
      if(*m_position == charT('R'))
2459
1
      {
2460
1
         ++m_position;
2461
1
         v = 0;
2462
1
         if(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark)
2463
0
         {
2464
            // Rewind to start of (? sequence:
2465
0
            --m_position;
2466
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2467
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2468
0
            return false;
2469
0
         }
2470
1
         goto insert_recursion;
2471
1
      }
2472
18.9k
      if(*m_position == charT('&'))
2473
369
      {
2474
369
         ++m_position;
2475
369
         const charT* base = m_position;
2476
6.85k
         while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2477
6.48k
            ++m_position;
2478
369
         if(m_position == m_end)
2479
0
         {
2480
            // Rewind to start of (? sequence:
2481
0
            --m_position;
2482
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2483
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2484
0
            return false;
2485
0
         }
2486
369
         v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2487
369
         goto insert_recursion;
2488
369
      }
2489
18.6k
      if(*m_position == charT('P'))
2490
34
      {
2491
34
         ++m_position;
2492
34
         if(m_position == m_end)
2493
0
         {
2494
            // Rewind to start of (? sequence:
2495
0
            --m_position;
2496
0
            while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2497
0
            fail(regex_constants::error_perl_extension, m_position - m_base);
2498
0
            return false;
2499
0
         }
2500
34
         if(*m_position == charT('>'))
2501
34
         {
2502
34
            ++m_position;
2503
34
            const charT* base = m_position;
2504
225
            while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
2505
191
               ++m_position;
2506
34
            if(m_position == m_end)
2507
1
            {
2508
               // Rewind to start of (? sequence:
2509
1
               --m_position;
2510
172
               while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2511
1
               fail(regex_constants::error_perl_extension, m_position - m_base);
2512
1
               return false;
2513
1
            }
2514
33
            v = static_cast<int>(hash_value_from_capture_name(base, m_position));
2515
33
            goto insert_recursion;
2516
34
         }
2517
34
      }
2518
      //
2519
      // lets assume that we have a (?imsx) group and try and parse it:
2520
      //
2521
19.4k
option_group_jump:
2522
19.4k
      regex_constants::syntax_option_type opts = parse_options();
2523
19.4k
      if(m_position == m_end)
2524
0
      {
2525
         // Rewind to start of (? sequence:
2526
0
         --m_position;
2527
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2528
0
         fail(regex_constants::error_perl_extension, m_position - m_base);
2529
0
         return false;
2530
0
      }
2531
      // make a note of whether we have a case change:
2532
19.4k
      m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
2533
19.4k
      pb->index = markid = 0;
2534
19.4k
      if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)
2535
18.5k
      {
2536
         // update flags and carry on as normal:
2537
18.5k
         this->flags(opts);
2538
18.5k
         restore_flags = false;
2539
18.5k
         old_case_change |= m_has_case_change; // defer end of scope by one ')'
2540
18.5k
      }
2541
832
      else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)
2542
824
      {
2543
         // update flags and carry on until the matching ')' is found:
2544
824
         this->flags(opts);
2545
824
         ++m_position;
2546
824
      }
2547
8
      else
2548
8
      {
2549
         // Rewind to start of (? sequence:
2550
8
         --m_position;
2551
15
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2552
8
         fail(regex_constants::error_perl_extension, m_position - m_base);
2553
8
         return false;
2554
8
      }
2555
2556
      // finally append a case change state if we need it:
2557
19.4k
      if(m_has_case_change)
2558
13.8k
      {
2559
13.8k
         static_cast<re_case*>(
2560
13.8k
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2561
13.8k
            )->icase = opts & regbase::icase;
2562
13.8k
      }
2563
2564
81.7k
   }
2565
   //
2566
   // now recursively add more states, this will terminate when we get to a
2567
   // matching ')' :
2568
   //
2569
81.7k
   parse_all();
2570
   //
2571
   // Unwind alternatives:
2572
   //
2573
81.7k
   if(0 == unwind_alts(last_paren_start))
2574
0
   {
2575
      // Rewind to start of (? sequence:
2576
0
      --m_position;
2577
0
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2578
0
      fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid alternation operators within (?...) block.");
2579
0
      return false;
2580
0
   }
2581
   //
2582
   // we either have a ')' or we have run out of characters prematurely:
2583
   //
2584
81.7k
   if(m_position == m_end)
2585
12
   {
2586
      // Rewind to start of (? sequence:
2587
12
      --m_position;
2588
18.4k
      while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2589
12
      this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
2590
12
      return false;
2591
12
   }
2592
81.7k
   BOOST_REGEX_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
2593
81.5k
   ++m_position;
2594
   //
2595
   // restore the flags:
2596
   //
2597
81.5k
   if(restore_flags)
2598
62.9k
   {
2599
      // append a case change state if we need it:
2600
62.9k
      if(m_has_case_change)
2601
38
      {
2602
38
         static_cast<re_case*>(
2603
38
            this->append_state(syntax_element_toggle_case, sizeof(re_case))
2604
38
            )->icase = old_flags & regbase::icase;
2605
38
      }
2606
62.9k
      this->flags(old_flags);
2607
62.9k
   }
2608
   //
2609
   // set up the jump pointer if we have one:
2610
   //
2611
81.5k
   if(jump_offset)
2612
1.21k
   {
2613
1.21k
      this->m_pdata->m_data.align();
2614
1.21k
      re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
2615
1.21k
      jmp->alt.i = this->m_pdata->m_data.size() - this->getoffset(jmp);
2616
1.21k
      if((this->m_last_state == jmp) && (markid != -2))
2617
0
      {
2618
         // Oops... we didn't have anything inside the assertion.
2619
         // Note we don't get here for negated forward lookahead as (?!)
2620
         // does have some uses.
2621
         // Rewind to start of (? sequence:
2622
0
         --m_position;
2623
0
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2624
0
         fail(regex_constants::error_perl_extension, m_position - m_base, "Invalid or empty zero width assertion.");
2625
0
         return false;
2626
0
      }
2627
1.21k
   }
2628
   //
2629
   // verify that if this is conditional expression, that we do have
2630
   // an alternative, if not add one:
2631
   //
2632
81.5k
   if(markid == -4)
2633
5.90k
   {
2634
5.90k
      re_syntax_base* b = this->getaddress(expected_alt_point);
2635
      // Make sure we have exactly one alternative following this state:
2636
5.90k
      if(b->type != syntax_element_alt)
2637
5.42k
      {
2638
5.42k
         re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));
2639
5.42k
         alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);
2640
5.42k
      }
2641
476
      else if(((std::ptrdiff_t)this->m_pdata->m_data.size() > (static_cast<re_alt*>(b)->alt.i + this->getoffset(b))) && (static_cast<re_alt*>(b)->alt.i > 0) && this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)
2642
3
      {
2643
         // Can't have seen more than one alternative:
2644
         // Rewind to start of (? sequence:
2645
3
         --m_position;
2646
4.80k
         while(this->m_traits.syntax_type(*m_position) != regex_constants::syntax_open_mark) --m_position;
2647
3
         fail(regex_constants::error_bad_pattern, m_position - m_base, "More than one alternation operator | was encountered inside a conditional expression.");
2648
3
         return false;
2649
3
      }
2650
473
      else
2651
473
      {
2652
         // We must *not* have seen an alternative inside a (DEFINE) block:
2653
473
         b = this->getaddress(b->next.i, b);