passenger 4.0.27 → 4.0.28
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of passenger might be problematic. Click here for more details.
- data.tar.gz.asc +7 -7
- data/.gitignore +1 -0
- data/NEWS +22 -0
- data/build/preprocessor.rb +10 -0
- data/build/rpm.rb +74 -65
- data/debian.template/rules.template +8 -0
- data/dev/copy_boost_headers.rb +11 -2
- data/doc/Users guide Apache.idmap.txt +161 -145
- data/doc/Users guide Apache.txt +12 -1
- data/doc/Users guide Nginx.idmap.txt +142 -126
- data/doc/Users guide Nginx.txt +14 -1
- data/doc/Users guide Standalone.txt +1 -0
- data/doc/users_guide_snippets/environment_variables.txt +1 -1
- data/doc/users_guide_snippets/installation.txt +2 -0
- data/doc/users_guide_snippets/tips.txt +118 -0
- data/ext/apache2/Configuration.cpp +0 -6
- data/ext/apache2/Configuration.hpp +0 -5
- data/ext/apache2/ConfigurationCommands.cpp +7 -0
- data/ext/apache2/ConfigurationFields.hpp +2 -0
- data/ext/apache2/ConfigurationSetters.cpp +24 -0
- data/ext/apache2/CreateDirConfig.cpp +1 -0
- data/ext/apache2/Hooks.cpp +0 -1
- data/ext/apache2/MergeDirConfig.cpp +7 -0
- data/ext/apache2/SetHeaders.cpp +5 -1
- data/ext/boost/cregex.hpp +39 -0
- data/ext/boost/libs/regex/src/c_regex_traits.cpp +193 -0
- data/ext/boost/libs/regex/src/cpp_regex_traits.cpp +117 -0
- data/ext/boost/libs/regex/src/cregex.cpp +660 -0
- data/ext/boost/libs/regex/src/instances.cpp +32 -0
- data/ext/boost/libs/regex/src/internals.hpp +35 -0
- data/ext/boost/libs/regex/src/posix_api.cpp +296 -0
- data/ext/boost/libs/regex/src/regex.cpp +227 -0
- data/ext/boost/libs/regex/src/regex_debug.cpp +59 -0
- data/ext/boost/libs/regex/src/regex_raw_buffer.cpp +72 -0
- data/ext/boost/libs/regex/src/regex_traits_defaults.cpp +692 -0
- data/ext/boost/libs/regex/src/static_mutex.cpp +179 -0
- data/ext/boost/libs/regex/src/wc_regex_traits.cpp +301 -0
- data/ext/boost/libs/regex/src/wide_posix_api.cpp +315 -0
- data/ext/boost/libs/regex/src/winstances.cpp +35 -0
- data/ext/boost/regex.h +100 -0
- data/ext/boost/regex.hpp +37 -0
- data/ext/boost/regex/concepts.hpp +1128 -0
- data/ext/boost/regex/config.hpp +435 -0
- data/ext/boost/regex/config/borland.hpp +72 -0
- data/ext/boost/regex/config/cwchar.hpp +207 -0
- data/ext/boost/regex/mfc.hpp +190 -0
- data/ext/boost/regex/pattern_except.hpp +100 -0
- data/ext/boost/regex/pending/object_cache.hpp +165 -0
- data/ext/boost/regex/pending/static_mutex.hpp +179 -0
- data/ext/boost/regex/pending/unicode_iterator.hpp +776 -0
- data/ext/boost/regex/regex_traits.hpp +35 -0
- data/ext/boost/regex/user.hpp +93 -0
- data/ext/boost/regex/v4/basic_regex.hpp +782 -0
- data/ext/boost/regex/v4/basic_regex_creator.hpp +1571 -0
- data/ext/boost/regex/v4/basic_regex_parser.hpp +2874 -0
- data/ext/boost/regex/v4/c_regex_traits.hpp +211 -0
- data/ext/boost/regex/v4/char_regex_traits.hpp +81 -0
- data/ext/boost/regex/v4/cpp_regex_traits.hpp +1099 -0
- data/ext/boost/regex/v4/cregex.hpp +330 -0
- data/ext/boost/regex/v4/error_type.hpp +59 -0
- data/ext/boost/regex/v4/fileiter.hpp +455 -0
- data/ext/boost/regex/v4/instances.hpp +222 -0
- data/ext/boost/regex/v4/iterator_category.hpp +91 -0
- data/ext/boost/regex/v4/iterator_traits.hpp +135 -0
- data/ext/boost/regex/v4/match_flags.hpp +138 -0
- data/ext/boost/regex/v4/match_results.hpp +702 -0
- data/ext/boost/regex/v4/mem_block_cache.hpp +99 -0
- data/ext/boost/regex/v4/perl_matcher.hpp +587 -0
- data/ext/boost/regex/v4/perl_matcher_common.hpp +996 -0
- data/ext/boost/regex/v4/perl_matcher_non_recursive.hpp +1642 -0
- data/ext/boost/regex/v4/perl_matcher_recursive.hpp +991 -0
- data/ext/boost/regex/v4/primary_transform.hpp +146 -0
- data/ext/boost/regex/v4/protected_call.hpp +81 -0
- data/ext/boost/regex/v4/regbase.hpp +180 -0
- data/ext/boost/regex/v4/regex.hpp +202 -0
- data/ext/boost/regex/v4/regex_format.hpp +1156 -0
- data/ext/boost/regex/v4/regex_fwd.hpp +73 -0
- data/ext/boost/regex/v4/regex_grep.hpp +155 -0
- data/ext/boost/regex/v4/regex_iterator.hpp +201 -0
- data/ext/boost/regex/v4/regex_match.hpp +382 -0
- data/ext/boost/regex/v4/regex_merge.hpp +93 -0
- data/ext/boost/regex/v4/regex_raw_buffer.hpp +210 -0
- data/ext/boost/regex/v4/regex_replace.hpp +99 -0
- data/ext/boost/regex/v4/regex_search.hpp +217 -0
- data/ext/boost/regex/v4/regex_split.hpp +172 -0
- data/ext/boost/regex/v4/regex_token_iterator.hpp +342 -0
- data/ext/boost/regex/v4/regex_traits.hpp +189 -0
- data/ext/boost/regex/v4/regex_traits_defaults.hpp +371 -0
- data/ext/boost/regex/v4/regex_workaround.hpp +232 -0
- data/ext/boost/regex/v4/states.hpp +301 -0
- data/ext/boost/regex/v4/sub_match.hpp +512 -0
- data/ext/boost/regex/v4/syntax_type.hpp +105 -0
- data/ext/boost/regex/v4/u32regex_iterator.hpp +193 -0
- data/ext/boost/regex/v4/u32regex_token_iterator.hpp +377 -0
- data/ext/boost/regex/v4/w32_regex_traits.hpp +741 -0
- data/ext/boost/regex_fwd.hpp +33 -0
- data/ext/common/AgentsStarter.h +0 -11
- data/ext/common/ApplicationPool2/Common.h +1 -7
- data/ext/common/ApplicationPool2/DirectSpawner.h +3 -3
- data/ext/common/ApplicationPool2/Group.h +166 -69
- data/ext/common/ApplicationPool2/Implementation.cpp +55 -10
- data/ext/common/ApplicationPool2/Options.h +45 -10
- data/ext/common/ApplicationPool2/PipeWatcher.h +1 -2
- data/ext/common/ApplicationPool2/Pool.h +29 -7
- data/ext/common/ApplicationPool2/Process.h +22 -3
- data/ext/common/ApplicationPool2/Session.h +1 -0
- data/ext/common/ApplicationPool2/SmartSpawner.h +5 -10
- data/ext/common/ApplicationPool2/Spawner.h +10 -15
- data/ext/common/ApplicationPool2/SuperGroup.h +10 -9
- data/ext/common/Constants.h +1 -3
- data/ext/common/Hooks.h +193 -0
- data/ext/common/Logging.cpp +67 -2
- data/ext/common/Logging.h +23 -1
- data/ext/common/Utils.cpp +0 -21
- data/ext/common/Utils.h +0 -42
- data/ext/common/Utils/CachedFileStat.hpp +1 -1
- data/ext/common/Utils/StrIntUtils.h +61 -14
- data/ext/common/Utils/StringMap.h +4 -0
- data/ext/common/agents/HelperAgent/AgentOptions.h +4 -4
- data/ext/common/agents/HelperAgent/Main.cpp +2 -3
- data/ext/common/agents/HelperAgent/RequestHandler.h +65 -2
- data/ext/common/agents/LoggingAgent/FilterSupport.h +3 -1
- data/ext/common/agents/Watchdog/Main.cpp +8 -72
- data/ext/nginx/CacheLocationConfig.c +29 -1
- data/ext/nginx/Configuration.c +0 -12
- data/ext/nginx/Configuration.h +0 -1
- data/ext/nginx/ConfigurationCommands.c +10 -0
- data/ext/nginx/ConfigurationFields.h +2 -0
- data/ext/nginx/CreateLocationConfig.c +4 -0
- data/ext/nginx/MergeLocationConfig.c +6 -0
- data/ext/oxt/system_calls.cpp +7 -1
- data/ext/oxt/system_calls.hpp +7 -7
- data/helper-scripts/node-loader.js +6 -2
- data/helper-scripts/rack-loader.rb +5 -2
- data/helper-scripts/rack-preloader.rb +5 -2
- data/lib/phusion_passenger.rb +1 -1
- data/lib/phusion_passenger/apache2/config_options.rb +8 -0
- data/lib/phusion_passenger/constants.rb +0 -1
- data/lib/phusion_passenger/nginx/config_options.rb +9 -2
- data/lib/phusion_passenger/platform_info/apache.rb +2 -1
- data/lib/phusion_passenger/platform_info/compiler.rb +15 -1
- data/lib/phusion_passenger/platform_info/cxx_portability.rb +2 -0
- data/node_lib/phusion_passenger/httplib_emulation.js +85 -17
- data/node_lib/phusion_passenger/request_handler.js +10 -2
- data/rpm/Vagrantfile +32 -0
- data/rpm/get_distro_id.py +4 -0
- data/test/cxx/ApplicationPool2/DirectSpawnerTest.cpp +2 -2
- data/test/cxx/ApplicationPool2/PoolTest.cpp +60 -9
- data/test/cxx/ApplicationPool2/SmartSpawnerTest.cpp +2 -6
- data/test/cxx/CachedFileStatTest.cpp +5 -5
- data/test/cxx/RequestHandlerTest.cpp +3 -6
- data/test/cxx/UtilsTest.cpp +30 -0
- data/test/node/httplib_emulation_spec.js +491 -0
- data/test/node/spec_helper.js +25 -0
- metadata +78 -2
- metadata.gz.asc +7 -7
@@ -0,0 +1,1642 @@
|
|
1
|
+
/*
|
2
|
+
*
|
3
|
+
* Copyright (c) 2002
|
4
|
+
* John Maddock
|
5
|
+
*
|
6
|
+
* Use, modification and distribution are subject to the
|
7
|
+
* Boost Software License, Version 1.0. (See accompanying file
|
8
|
+
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
9
|
+
*
|
10
|
+
*/
|
11
|
+
|
12
|
+
/*
|
13
|
+
* LOCATION: see http://www.boost.org for most recent version.
|
14
|
+
* FILE perl_matcher_common.cpp
|
15
|
+
* VERSION see <boost/version.hpp>
|
16
|
+
* DESCRIPTION: Definitions of perl_matcher member functions that are
|
17
|
+
* specific to the non-recursive implementation.
|
18
|
+
*/
|
19
|
+
|
20
|
+
#ifndef BOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP
|
21
|
+
#define BOOST_REGEX_V4_PERL_MATCHER_NON_RECURSIVE_HPP
|
22
|
+
|
23
|
+
#include <new>
|
24
|
+
|
25
|
+
#ifdef BOOST_MSVC
|
26
|
+
#pragma warning(push)
|
27
|
+
#pragma warning(disable: 4103)
|
28
|
+
#endif
|
29
|
+
#ifdef BOOST_HAS_ABI_HEADERS
|
30
|
+
# include BOOST_ABI_PREFIX
|
31
|
+
#endif
|
32
|
+
#ifdef BOOST_MSVC
|
33
|
+
#pragma warning(pop)
|
34
|
+
#endif
|
35
|
+
#ifdef BOOST_MSVC
|
36
|
+
# pragma warning(push)
|
37
|
+
# pragma warning(disable: 4800)
|
38
|
+
#endif
|
39
|
+
|
40
|
+
namespace boost{
|
41
|
+
namespace re_detail{
|
42
|
+
|
43
|
+
template <class T>
|
44
|
+
inline void inplace_destroy(T* p)
|
45
|
+
{
|
46
|
+
(void)p; // warning suppression
|
47
|
+
p->~T();
|
48
|
+
}
|
49
|
+
|
50
|
+
struct saved_state
|
51
|
+
{
|
52
|
+
union{
|
53
|
+
unsigned int state_id;
|
54
|
+
// this padding ensures correct alignment on 64-bit platforms:
|
55
|
+
std::size_t padding1;
|
56
|
+
std::ptrdiff_t padding2;
|
57
|
+
void* padding3;
|
58
|
+
};
|
59
|
+
saved_state(unsigned i) : state_id(i) {}
|
60
|
+
};
|
61
|
+
|
62
|
+
template <class BidiIterator>
|
63
|
+
struct saved_matched_paren : public saved_state
|
64
|
+
{
|
65
|
+
int index;
|
66
|
+
sub_match<BidiIterator> sub;
|
67
|
+
saved_matched_paren(int i, const sub_match<BidiIterator>& s) : saved_state(1), index(i), sub(s){};
|
68
|
+
};
|
69
|
+
|
70
|
+
template <class BidiIterator>
|
71
|
+
struct saved_position : public saved_state
|
72
|
+
{
|
73
|
+
const re_syntax_base* pstate;
|
74
|
+
BidiIterator position;
|
75
|
+
saved_position(const re_syntax_base* ps, BidiIterator pos, int i) : saved_state(i), pstate(ps), position(pos){};
|
76
|
+
};
|
77
|
+
|
78
|
+
template <class BidiIterator>
|
79
|
+
struct saved_assertion : public saved_position<BidiIterator>
|
80
|
+
{
|
81
|
+
bool positive;
|
82
|
+
saved_assertion(bool p, const re_syntax_base* ps, BidiIterator pos)
|
83
|
+
: saved_position<BidiIterator>(ps, pos, saved_type_assertion), positive(p){};
|
84
|
+
};
|
85
|
+
|
86
|
+
template <class BidiIterator>
|
87
|
+
struct saved_repeater : public saved_state
|
88
|
+
{
|
89
|
+
repeater_count<BidiIterator> count;
|
90
|
+
saved_repeater(int i, repeater_count<BidiIterator>** s, BidiIterator start)
|
91
|
+
: saved_state(saved_state_repeater_count), count(i,s,start){}
|
92
|
+
};
|
93
|
+
|
94
|
+
struct saved_extra_block : public saved_state
|
95
|
+
{
|
96
|
+
saved_state *base, *end;
|
97
|
+
saved_extra_block(saved_state* b, saved_state* e)
|
98
|
+
: saved_state(saved_state_extra_block), base(b), end(e) {}
|
99
|
+
};
|
100
|
+
|
101
|
+
struct save_state_init
|
102
|
+
{
|
103
|
+
saved_state** stack;
|
104
|
+
save_state_init(saved_state** base, saved_state** end)
|
105
|
+
: stack(base)
|
106
|
+
{
|
107
|
+
*base = static_cast<saved_state*>(get_mem_block());
|
108
|
+
*end = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(*base)+BOOST_REGEX_BLOCKSIZE);
|
109
|
+
--(*end);
|
110
|
+
(void) new (*end)saved_state(0);
|
111
|
+
BOOST_ASSERT(*end > *base);
|
112
|
+
}
|
113
|
+
~save_state_init()
|
114
|
+
{
|
115
|
+
put_mem_block(*stack);
|
116
|
+
*stack = 0;
|
117
|
+
}
|
118
|
+
};
|
119
|
+
|
120
|
+
template <class BidiIterator>
|
121
|
+
struct saved_single_repeat : public saved_state
|
122
|
+
{
|
123
|
+
std::size_t count;
|
124
|
+
const re_repeat* rep;
|
125
|
+
BidiIterator last_position;
|
126
|
+
saved_single_repeat(std::size_t c, const re_repeat* r, BidiIterator lp, int arg_id)
|
127
|
+
: saved_state(arg_id), count(c), rep(r), last_position(lp){}
|
128
|
+
};
|
129
|
+
|
130
|
+
template <class Results>
|
131
|
+
struct saved_recursion : public saved_state
|
132
|
+
{
|
133
|
+
saved_recursion(int idx, const re_syntax_base* p, Results* pr)
|
134
|
+
: saved_state(14), recursion_id(idx), preturn_address(p), results(*pr)
|
135
|
+
{}
|
136
|
+
int recursion_id;
|
137
|
+
const re_syntax_base* preturn_address;
|
138
|
+
Results results;
|
139
|
+
};
|
140
|
+
|
141
|
+
template <class BidiIterator, class Allocator, class traits>
|
142
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
|
143
|
+
{
|
144
|
+
static matcher_proc_type const s_match_vtable[30] =
|
145
|
+
{
|
146
|
+
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
|
147
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
|
148
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_literal,
|
149
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
|
150
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
|
151
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_wild,
|
152
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_match,
|
153
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
|
154
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
|
155
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
|
156
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
|
157
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
|
158
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
|
159
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_backref,
|
160
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
|
161
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_set,
|
162
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_jump,
|
163
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_alt,
|
164
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_rep,
|
165
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_combining,
|
166
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
|
167
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
|
168
|
+
// Although this next line *should* be evaluated at compile time, in practice
|
169
|
+
// some compilers (VC++) emit run-time initialisation which breaks thread
|
170
|
+
// safety, so use a dispatch function instead:
|
171
|
+
//(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
|
172
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
|
173
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
|
174
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
|
175
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
|
176
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
|
177
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
|
178
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
|
179
|
+
&perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
|
180
|
+
};
|
181
|
+
|
182
|
+
push_recursion_stopper();
|
183
|
+
do{
|
184
|
+
while(pstate)
|
185
|
+
{
|
186
|
+
matcher_proc_type proc = s_match_vtable[pstate->type];
|
187
|
+
++state_count;
|
188
|
+
if(!(this->*proc)())
|
189
|
+
{
|
190
|
+
if(state_count > max_state_count)
|
191
|
+
raise_error(traits_inst, regex_constants::error_complexity);
|
192
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
193
|
+
m_has_partial_match = true;
|
194
|
+
bool successful_unwind = unwind(false);
|
195
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
196
|
+
m_has_partial_match = true;
|
197
|
+
if(false == successful_unwind)
|
198
|
+
return m_recursive_result;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}while(unwind(true));
|
202
|
+
return m_recursive_result;
|
203
|
+
}
|
204
|
+
|
205
|
+
template <class BidiIterator, class Allocator, class traits>
|
206
|
+
void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
|
207
|
+
{
|
208
|
+
if(used_block_count)
|
209
|
+
{
|
210
|
+
--used_block_count;
|
211
|
+
saved_state* stack_base;
|
212
|
+
saved_state* backup_state;
|
213
|
+
stack_base = static_cast<saved_state*>(get_mem_block());
|
214
|
+
backup_state = reinterpret_cast<saved_state*>(reinterpret_cast<char*>(stack_base)+BOOST_REGEX_BLOCKSIZE);
|
215
|
+
saved_extra_block* block = static_cast<saved_extra_block*>(backup_state);
|
216
|
+
--block;
|
217
|
+
(void) new (block) saved_extra_block(m_stack_base, m_backup_state);
|
218
|
+
m_stack_base = stack_base;
|
219
|
+
m_backup_state = block;
|
220
|
+
}
|
221
|
+
else
|
222
|
+
raise_error(traits_inst, regex_constants::error_stack);
|
223
|
+
}
|
224
|
+
|
225
|
+
template <class BidiIterator, class Allocator, class traits>
|
226
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
|
227
|
+
{
|
228
|
+
//BOOST_ASSERT(index);
|
229
|
+
saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
|
230
|
+
--pmp;
|
231
|
+
if(pmp < m_stack_base)
|
232
|
+
{
|
233
|
+
extend_stack();
|
234
|
+
pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
|
235
|
+
--pmp;
|
236
|
+
}
|
237
|
+
(void) new (pmp)saved_matched_paren<BidiIterator>(index, sub);
|
238
|
+
m_backup_state = pmp;
|
239
|
+
}
|
240
|
+
|
241
|
+
template <class BidiIterator, class Allocator, class traits>
|
242
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()
|
243
|
+
{
|
244
|
+
saved_state* pmp = m_backup_state;
|
245
|
+
--pmp;
|
246
|
+
if(pmp < m_stack_base)
|
247
|
+
{
|
248
|
+
extend_stack();
|
249
|
+
pmp = m_backup_state;
|
250
|
+
--pmp;
|
251
|
+
}
|
252
|
+
(void) new (pmp)saved_state(saved_type_recurse);
|
253
|
+
m_backup_state = pmp;
|
254
|
+
}
|
255
|
+
|
256
|
+
template <class BidiIterator, class Allocator, class traits>
|
257
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)
|
258
|
+
{
|
259
|
+
saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
|
260
|
+
--pmp;
|
261
|
+
if(pmp < m_stack_base)
|
262
|
+
{
|
263
|
+
extend_stack();
|
264
|
+
pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
|
265
|
+
--pmp;
|
266
|
+
}
|
267
|
+
(void) new (pmp)saved_assertion<BidiIterator>(positive, ps, position);
|
268
|
+
m_backup_state = pmp;
|
269
|
+
}
|
270
|
+
|
271
|
+
template <class BidiIterator, class Allocator, class traits>
|
272
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)
|
273
|
+
{
|
274
|
+
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
275
|
+
--pmp;
|
276
|
+
if(pmp < m_stack_base)
|
277
|
+
{
|
278
|
+
extend_stack();
|
279
|
+
pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
280
|
+
--pmp;
|
281
|
+
}
|
282
|
+
(void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_alt);
|
283
|
+
m_backup_state = pmp;
|
284
|
+
}
|
285
|
+
|
286
|
+
template <class BidiIterator, class Allocator, class traits>
|
287
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)
|
288
|
+
{
|
289
|
+
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
290
|
+
--pmp;
|
291
|
+
if(pmp < m_stack_base)
|
292
|
+
{
|
293
|
+
extend_stack();
|
294
|
+
pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
295
|
+
--pmp;
|
296
|
+
}
|
297
|
+
(void) new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);
|
298
|
+
m_backup_state = pmp;
|
299
|
+
}
|
300
|
+
|
301
|
+
template <class BidiIterator, class Allocator, class traits>
|
302
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
|
303
|
+
{
|
304
|
+
saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
|
305
|
+
--pmp;
|
306
|
+
if(pmp < m_stack_base)
|
307
|
+
{
|
308
|
+
extend_stack();
|
309
|
+
pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
|
310
|
+
--pmp;
|
311
|
+
}
|
312
|
+
(void) new (pmp)saved_repeater<BidiIterator>(i, s, position);
|
313
|
+
m_backup_state = pmp;
|
314
|
+
}
|
315
|
+
|
316
|
+
template <class BidiIterator, class Allocator, class traits>
|
317
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(std::size_t c, const re_repeat* r, BidiIterator last_position, int state_id)
|
318
|
+
{
|
319
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
320
|
+
--pmp;
|
321
|
+
if(pmp < m_stack_base)
|
322
|
+
{
|
323
|
+
extend_stack();
|
324
|
+
pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
325
|
+
--pmp;
|
326
|
+
}
|
327
|
+
(void) new (pmp)saved_single_repeat<BidiIterator>(c, r, last_position, state_id);
|
328
|
+
m_backup_state = pmp;
|
329
|
+
}
|
330
|
+
|
331
|
+
template <class BidiIterator, class Allocator, class traits>
|
332
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int idx, const re_syntax_base* p, results_type* presults)
|
333
|
+
{
|
334
|
+
saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
335
|
+
--pmp;
|
336
|
+
if(pmp < m_stack_base)
|
337
|
+
{
|
338
|
+
extend_stack();
|
339
|
+
pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
340
|
+
--pmp;
|
341
|
+
}
|
342
|
+
(void) new (pmp)saved_recursion<results_type>(idx, p, presults);
|
343
|
+
m_backup_state = pmp;
|
344
|
+
}
|
345
|
+
|
346
|
+
template <class BidiIterator, class Allocator, class traits>
|
347
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
|
348
|
+
{
|
349
|
+
int index = static_cast<const re_brace*>(pstate)->index;
|
350
|
+
icase = static_cast<const re_brace*>(pstate)->icase;
|
351
|
+
switch(index)
|
352
|
+
{
|
353
|
+
case 0:
|
354
|
+
pstate = pstate->next.p;
|
355
|
+
break;
|
356
|
+
case -1:
|
357
|
+
case -2:
|
358
|
+
{
|
359
|
+
// forward lookahead assert:
|
360
|
+
const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
|
361
|
+
pstate = pstate->next.p->next.p;
|
362
|
+
push_assertion(next_pstate, index == -1);
|
363
|
+
break;
|
364
|
+
}
|
365
|
+
case -3:
|
366
|
+
{
|
367
|
+
// independent sub-expression, currently this is always recursive:
|
368
|
+
bool old_independent = m_independent;
|
369
|
+
m_independent = true;
|
370
|
+
const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
|
371
|
+
pstate = pstate->next.p->next.p;
|
372
|
+
bool r = match_all_states();
|
373
|
+
pstate = next_pstate;
|
374
|
+
m_independent = old_independent;
|
375
|
+
#ifdef BOOST_REGEX_MATCH_EXTRA
|
376
|
+
if(r && (m_match_flags & match_extra))
|
377
|
+
{
|
378
|
+
//
|
379
|
+
// our captures have been stored in *m_presult
|
380
|
+
// we need to unpack them, and insert them
|
381
|
+
// back in the right order when we unwind the stack:
|
382
|
+
//
|
383
|
+
match_results<BidiIterator, Allocator> temp_match(*m_presult);
|
384
|
+
unsigned i;
|
385
|
+
for(i = 0; i < temp_match.size(); ++i)
|
386
|
+
(*m_presult)[i].get_captures().clear();
|
387
|
+
// match everything else:
|
388
|
+
r = match_all_states();
|
389
|
+
// now place the stored captures back:
|
390
|
+
for(i = 0; i < temp_match.size(); ++i)
|
391
|
+
{
|
392
|
+
typedef typename sub_match<BidiIterator>::capture_sequence_type seq;
|
393
|
+
seq& s1 = (*m_presult)[i].get_captures();
|
394
|
+
const seq& s2 = temp_match[i].captures();
|
395
|
+
s1.insert(
|
396
|
+
s1.end(),
|
397
|
+
s2.begin(),
|
398
|
+
s2.end());
|
399
|
+
}
|
400
|
+
}
|
401
|
+
#endif
|
402
|
+
return r;
|
403
|
+
}
|
404
|
+
case -4:
|
405
|
+
{
|
406
|
+
// conditional expression:
|
407
|
+
const re_alt* alt = static_cast<const re_alt*>(pstate->next.p);
|
408
|
+
BOOST_ASSERT(alt->type == syntax_element_alt);
|
409
|
+
pstate = alt->next.p;
|
410
|
+
if(pstate->type == syntax_element_assert_backref)
|
411
|
+
{
|
412
|
+
if(!match_assert_backref())
|
413
|
+
pstate = alt->alt.p;
|
414
|
+
break;
|
415
|
+
}
|
416
|
+
else
|
417
|
+
{
|
418
|
+
// zero width assertion, have to match this recursively:
|
419
|
+
BOOST_ASSERT(pstate->type == syntax_element_startmark);
|
420
|
+
bool negated = static_cast<const re_brace*>(pstate)->index == -2;
|
421
|
+
BidiIterator saved_position = position;
|
422
|
+
const re_syntax_base* next_pstate = static_cast<const re_jump*>(pstate->next.p)->alt.p->next.p;
|
423
|
+
pstate = pstate->next.p->next.p;
|
424
|
+
bool r = match_all_states();
|
425
|
+
position = saved_position;
|
426
|
+
if(negated)
|
427
|
+
r = !r;
|
428
|
+
if(r)
|
429
|
+
pstate = next_pstate;
|
430
|
+
else
|
431
|
+
pstate = alt->alt.p;
|
432
|
+
break;
|
433
|
+
}
|
434
|
+
}
|
435
|
+
case -5:
|
436
|
+
{
|
437
|
+
push_matched_paren(0, (*m_presult)[0]);
|
438
|
+
m_presult->set_first(position, 0, true);
|
439
|
+
pstate = pstate->next.p;
|
440
|
+
break;
|
441
|
+
}
|
442
|
+
default:
|
443
|
+
{
|
444
|
+
BOOST_ASSERT(index > 0);
|
445
|
+
if((m_match_flags & match_nosubs) == 0)
|
446
|
+
{
|
447
|
+
push_matched_paren(index, (*m_presult)[index]);
|
448
|
+
m_presult->set_first(position, index);
|
449
|
+
}
|
450
|
+
pstate = pstate->next.p;
|
451
|
+
break;
|
452
|
+
}
|
453
|
+
}
|
454
|
+
return true;
|
455
|
+
}
|
456
|
+
|
457
|
+
template <class BidiIterator, class Allocator, class traits>
|
458
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
|
459
|
+
{
|
460
|
+
bool take_first, take_second;
|
461
|
+
const re_alt* jmp = static_cast<const re_alt*>(pstate);
|
462
|
+
|
463
|
+
// find out which of these two alternatives we need to take:
|
464
|
+
if(position == last)
|
465
|
+
{
|
466
|
+
take_first = jmp->can_be_null & mask_take;
|
467
|
+
take_second = jmp->can_be_null & mask_skip;
|
468
|
+
}
|
469
|
+
else
|
470
|
+
{
|
471
|
+
take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
|
472
|
+
take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
|
473
|
+
}
|
474
|
+
|
475
|
+
if(take_first)
|
476
|
+
{
|
477
|
+
// we can take the first alternative,
|
478
|
+
// see if we need to push next alternative:
|
479
|
+
if(take_second)
|
480
|
+
{
|
481
|
+
push_alt(jmp->alt.p);
|
482
|
+
}
|
483
|
+
pstate = pstate->next.p;
|
484
|
+
return true;
|
485
|
+
}
|
486
|
+
if(take_second)
|
487
|
+
{
|
488
|
+
pstate = jmp->alt.p;
|
489
|
+
return true;
|
490
|
+
}
|
491
|
+
return false; // neither option is possible
|
492
|
+
}
|
493
|
+
|
494
|
+
template <class BidiIterator, class Allocator, class traits>
|
495
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
|
496
|
+
{
|
497
|
+
#ifdef BOOST_MSVC
|
498
|
+
#pragma warning(push)
|
499
|
+
#pragma warning(disable:4127 4244)
|
500
|
+
#endif
|
501
|
+
#ifdef __BORLANDC__
|
502
|
+
#pragma option push -w-8008 -w-8066 -w-8004
|
503
|
+
#endif
|
504
|
+
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
|
505
|
+
|
506
|
+
// find out which of these two alternatives we need to take:
|
507
|
+
bool take_first, take_second;
|
508
|
+
if(position == last)
|
509
|
+
{
|
510
|
+
take_first = rep->can_be_null & mask_take;
|
511
|
+
take_second = rep->can_be_null & mask_skip;
|
512
|
+
}
|
513
|
+
else
|
514
|
+
{
|
515
|
+
take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
|
516
|
+
take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
|
517
|
+
}
|
518
|
+
|
519
|
+
if((m_backup_state->state_id != saved_state_repeater_count)
|
520
|
+
|| (static_cast<saved_repeater<BidiIterator>*>(m_backup_state)->count.get_id() != rep->state_id)
|
521
|
+
|| (next_count->get_id() != rep->state_id))
|
522
|
+
{
|
523
|
+
// we're moving to a different repeat from the last
|
524
|
+
// one, so set up a counter object:
|
525
|
+
push_repeater_count(rep->state_id, &next_count);
|
526
|
+
}
|
527
|
+
//
|
528
|
+
// If we've had at least one repeat already, and the last one
|
529
|
+
// matched the NULL string then set the repeat count to
|
530
|
+
// maximum:
|
531
|
+
//
|
532
|
+
next_count->check_null_repeat(position, rep->max);
|
533
|
+
|
534
|
+
if(next_count->get_count() < rep->min)
|
535
|
+
{
|
536
|
+
// we must take the repeat:
|
537
|
+
if(take_first)
|
538
|
+
{
|
539
|
+
// increase the counter:
|
540
|
+
++(*next_count);
|
541
|
+
pstate = rep->next.p;
|
542
|
+
return true;
|
543
|
+
}
|
544
|
+
return false;
|
545
|
+
}
|
546
|
+
|
547
|
+
bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
|
548
|
+
if(greedy)
|
549
|
+
{
|
550
|
+
// try and take the repeat if we can:
|
551
|
+
if((next_count->get_count() < rep->max) && take_first)
|
552
|
+
{
|
553
|
+
if(take_second)
|
554
|
+
{
|
555
|
+
// store position in case we fail:
|
556
|
+
push_alt(rep->alt.p);
|
557
|
+
}
|
558
|
+
// increase the counter:
|
559
|
+
++(*next_count);
|
560
|
+
pstate = rep->next.p;
|
561
|
+
return true;
|
562
|
+
}
|
563
|
+
else if(take_second)
|
564
|
+
{
|
565
|
+
pstate = rep->alt.p;
|
566
|
+
return true;
|
567
|
+
}
|
568
|
+
return false; // can't take anything, fail...
|
569
|
+
}
|
570
|
+
else // non-greedy
|
571
|
+
{
|
572
|
+
// try and skip the repeat if we can:
|
573
|
+
if(take_second)
|
574
|
+
{
|
575
|
+
if((next_count->get_count() < rep->max) && take_first)
|
576
|
+
{
|
577
|
+
// store position in case we fail:
|
578
|
+
push_non_greedy_repeat(rep->next.p);
|
579
|
+
}
|
580
|
+
pstate = rep->alt.p;
|
581
|
+
return true;
|
582
|
+
}
|
583
|
+
if((next_count->get_count() < rep->max) && take_first)
|
584
|
+
{
|
585
|
+
// increase the counter:
|
586
|
+
++(*next_count);
|
587
|
+
pstate = rep->next.p;
|
588
|
+
return true;
|
589
|
+
}
|
590
|
+
}
|
591
|
+
return false;
|
592
|
+
#ifdef __BORLANDC__
|
593
|
+
#pragma option pop
|
594
|
+
#endif
|
595
|
+
#ifdef BOOST_MSVC
|
596
|
+
#pragma warning(pop)
|
597
|
+
#endif
|
598
|
+
}
|
599
|
+
|
600
|
+
template <class BidiIterator, class Allocator, class traits>
|
601
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
|
602
|
+
{
|
603
|
+
unsigned count = 0;
|
604
|
+
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
|
605
|
+
re_syntax_base* psingle = rep->next.p;
|
606
|
+
// match compulsary repeats first:
|
607
|
+
while(count < rep->min)
|
608
|
+
{
|
609
|
+
pstate = psingle;
|
610
|
+
if(!match_wild())
|
611
|
+
return false;
|
612
|
+
++count;
|
613
|
+
}
|
614
|
+
bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
|
615
|
+
if(greedy)
|
616
|
+
{
|
617
|
+
// repeat for as long as we can:
|
618
|
+
while(count < rep->max)
|
619
|
+
{
|
620
|
+
pstate = psingle;
|
621
|
+
if(!match_wild())
|
622
|
+
break;
|
623
|
+
++count;
|
624
|
+
}
|
625
|
+
// remember where we got to if this is a leading repeat:
|
626
|
+
if((rep->leading) && (count < rep->max))
|
627
|
+
restart = position;
|
628
|
+
// push backtrack info if available:
|
629
|
+
if(count - rep->min)
|
630
|
+
push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
|
631
|
+
// jump to next state:
|
632
|
+
pstate = rep->alt.p;
|
633
|
+
return true;
|
634
|
+
}
|
635
|
+
else
|
636
|
+
{
|
637
|
+
// non-greedy, push state and return true if we can skip:
|
638
|
+
if(count < rep->max)
|
639
|
+
push_single_repeat(count, rep, position, saved_state_rep_slow_dot);
|
640
|
+
pstate = rep->alt.p;
|
641
|
+
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
|
642
|
+
}
|
643
|
+
}
|
644
|
+
|
645
|
+
template <class BidiIterator, class Allocator, class traits>
|
646
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
|
647
|
+
{
|
648
|
+
if(m_match_flags & match_not_dot_null)
|
649
|
+
return match_dot_repeat_slow();
|
650
|
+
if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
|
651
|
+
return match_dot_repeat_slow();
|
652
|
+
|
653
|
+
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
|
654
|
+
bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
|
655
|
+
unsigned count = static_cast<unsigned>((std::min)(static_cast<unsigned>(::boost::re_detail::distance(position, last)), static_cast<unsigned>(greedy ? rep->max : rep->min)));
|
656
|
+
if(rep->min > count)
|
657
|
+
{
|
658
|
+
position = last;
|
659
|
+
return false; // not enough text left to match
|
660
|
+
}
|
661
|
+
std::advance(position, count);
|
662
|
+
|
663
|
+
if(greedy)
|
664
|
+
{
|
665
|
+
if((rep->leading) && (count < rep->max))
|
666
|
+
restart = position;
|
667
|
+
// push backtrack info if available:
|
668
|
+
if(count - rep->min)
|
669
|
+
push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
|
670
|
+
// jump to next state:
|
671
|
+
pstate = rep->alt.p;
|
672
|
+
return true;
|
673
|
+
}
|
674
|
+
else
|
675
|
+
{
|
676
|
+
// non-greedy, push state and return true if we can skip:
|
677
|
+
if(count < rep->max)
|
678
|
+
push_single_repeat(count, rep, position, saved_state_rep_fast_dot);
|
679
|
+
pstate = rep->alt.p;
|
680
|
+
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
|
681
|
+
}
|
682
|
+
}
|
683
|
+
|
684
|
+
template <class BidiIterator, class Allocator, class traits>
|
685
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
|
686
|
+
{
|
687
|
+
#ifdef BOOST_MSVC
|
688
|
+
#pragma warning(push)
|
689
|
+
#pragma warning(disable:4127)
|
690
|
+
#endif
|
691
|
+
#ifdef __BORLANDC__
|
692
|
+
#pragma option push -w-8008 -w-8066 -w-8004
|
693
|
+
#endif
|
694
|
+
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
|
695
|
+
BOOST_ASSERT(1 == static_cast<const re_literal*>(rep->next.p)->length);
|
696
|
+
const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(rep->next.p) + 1);
|
697
|
+
std::size_t count = 0;
|
698
|
+
//
|
699
|
+
// start by working out how much we can skip:
|
700
|
+
//
|
701
|
+
bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
|
702
|
+
std::size_t desired = greedy ? rep->max : rep->min;
|
703
|
+
if(::boost::is_random_access_iterator<BidiIterator>::value)
|
704
|
+
{
|
705
|
+
BidiIterator end = position;
|
706
|
+
std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
|
707
|
+
BidiIterator origin(position);
|
708
|
+
while((position != end) && (traits_inst.translate(*position, icase) == what))
|
709
|
+
{
|
710
|
+
++position;
|
711
|
+
}
|
712
|
+
count = (unsigned)::boost::re_detail::distance(origin, position);
|
713
|
+
}
|
714
|
+
else
|
715
|
+
{
|
716
|
+
while((count < desired) && (position != last) && (traits_inst.translate(*position, icase) == what))
|
717
|
+
{
|
718
|
+
++position;
|
719
|
+
++count;
|
720
|
+
}
|
721
|
+
}
|
722
|
+
|
723
|
+
if(count < rep->min)
|
724
|
+
return false;
|
725
|
+
|
726
|
+
if(greedy)
|
727
|
+
{
|
728
|
+
if((rep->leading) && (count < rep->max))
|
729
|
+
restart = position;
|
730
|
+
// push backtrack info if available:
|
731
|
+
if(count - rep->min)
|
732
|
+
push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
|
733
|
+
// jump to next state:
|
734
|
+
pstate = rep->alt.p;
|
735
|
+
return true;
|
736
|
+
}
|
737
|
+
else
|
738
|
+
{
|
739
|
+
// non-greedy, push state and return true if we can skip:
|
740
|
+
if(count < rep->max)
|
741
|
+
push_single_repeat(count, rep, position, saved_state_rep_char);
|
742
|
+
pstate = rep->alt.p;
|
743
|
+
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
|
744
|
+
}
|
745
|
+
#ifdef __BORLANDC__
|
746
|
+
#pragma option pop
|
747
|
+
#endif
|
748
|
+
#ifdef BOOST_MSVC
|
749
|
+
#pragma warning(pop)
|
750
|
+
#endif
|
751
|
+
}
|
752
|
+
|
753
|
+
template <class BidiIterator, class Allocator, class traits>
|
754
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
|
755
|
+
{
|
756
|
+
#ifdef BOOST_MSVC
|
757
|
+
#pragma warning(push)
|
758
|
+
#pragma warning(disable:4127)
|
759
|
+
#endif
|
760
|
+
#ifdef __BORLANDC__
|
761
|
+
#pragma option push -w-8008 -w-8066 -w-8004
|
762
|
+
#endif
|
763
|
+
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
|
764
|
+
const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
|
765
|
+
std::size_t count = 0;
|
766
|
+
//
|
767
|
+
// start by working out how much we can skip:
|
768
|
+
//
|
769
|
+
bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
|
770
|
+
std::size_t desired = greedy ? rep->max : rep->min;
|
771
|
+
if(::boost::is_random_access_iterator<BidiIterator>::value)
|
772
|
+
{
|
773
|
+
BidiIterator end = position;
|
774
|
+
std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
|
775
|
+
BidiIterator origin(position);
|
776
|
+
while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
|
777
|
+
{
|
778
|
+
++position;
|
779
|
+
}
|
780
|
+
count = (unsigned)::boost::re_detail::distance(origin, position);
|
781
|
+
}
|
782
|
+
else
|
783
|
+
{
|
784
|
+
while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
|
785
|
+
{
|
786
|
+
++position;
|
787
|
+
++count;
|
788
|
+
}
|
789
|
+
}
|
790
|
+
|
791
|
+
if(count < rep->min)
|
792
|
+
return false;
|
793
|
+
|
794
|
+
if(greedy)
|
795
|
+
{
|
796
|
+
if((rep->leading) && (count < rep->max))
|
797
|
+
restart = position;
|
798
|
+
// push backtrack info if available:
|
799
|
+
if(count - rep->min)
|
800
|
+
push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
|
801
|
+
// jump to next state:
|
802
|
+
pstate = rep->alt.p;
|
803
|
+
return true;
|
804
|
+
}
|
805
|
+
else
|
806
|
+
{
|
807
|
+
// non-greedy, push state and return true if we can skip:
|
808
|
+
if(count < rep->max)
|
809
|
+
push_single_repeat(count, rep, position, saved_state_rep_short_set);
|
810
|
+
pstate = rep->alt.p;
|
811
|
+
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
|
812
|
+
}
|
813
|
+
#ifdef __BORLANDC__
|
814
|
+
#pragma option pop
|
815
|
+
#endif
|
816
|
+
#ifdef BOOST_MSVC
|
817
|
+
#pragma warning(pop)
|
818
|
+
#endif
|
819
|
+
}
|
820
|
+
|
821
|
+
template <class BidiIterator, class Allocator, class traits>
|
822
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
|
823
|
+
{
|
824
|
+
#ifdef BOOST_MSVC
|
825
|
+
#pragma warning(push)
|
826
|
+
#pragma warning(disable:4127)
|
827
|
+
#endif
|
828
|
+
#ifdef __BORLANDC__
|
829
|
+
#pragma option push -w-8008 -w-8066 -w-8004
|
830
|
+
#endif
|
831
|
+
typedef typename traits::char_class_type m_type;
|
832
|
+
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
|
833
|
+
const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate->next.p);
|
834
|
+
std::size_t count = 0;
|
835
|
+
//
|
836
|
+
// start by working out how much we can skip:
|
837
|
+
//
|
838
|
+
bool greedy = (rep->greedy) && (!(m_match_flags & regex_constants::match_any) || m_independent);
|
839
|
+
std::size_t desired = greedy ? rep->max : rep->min;
|
840
|
+
if(::boost::is_random_access_iterator<BidiIterator>::value)
|
841
|
+
{
|
842
|
+
BidiIterator end = position;
|
843
|
+
std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
|
844
|
+
BidiIterator origin(position);
|
845
|
+
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
|
846
|
+
{
|
847
|
+
++position;
|
848
|
+
}
|
849
|
+
count = (unsigned)::boost::re_detail::distance(origin, position);
|
850
|
+
}
|
851
|
+
else
|
852
|
+
{
|
853
|
+
while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
|
854
|
+
{
|
855
|
+
++position;
|
856
|
+
++count;
|
857
|
+
}
|
858
|
+
}
|
859
|
+
|
860
|
+
if(count < rep->min)
|
861
|
+
return false;
|
862
|
+
|
863
|
+
if(greedy)
|
864
|
+
{
|
865
|
+
if((rep->leading) && (count < rep->max))
|
866
|
+
restart = position;
|
867
|
+
// push backtrack info if available:
|
868
|
+
if(count - rep->min)
|
869
|
+
push_single_repeat(count, rep, position, saved_state_greedy_single_repeat);
|
870
|
+
// jump to next state:
|
871
|
+
pstate = rep->alt.p;
|
872
|
+
return true;
|
873
|
+
}
|
874
|
+
else
|
875
|
+
{
|
876
|
+
// non-greedy, push state and return true if we can skip:
|
877
|
+
if(count < rep->max)
|
878
|
+
push_single_repeat(count, rep, position, saved_state_rep_long_set);
|
879
|
+
pstate = rep->alt.p;
|
880
|
+
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
|
881
|
+
}
|
882
|
+
#ifdef __BORLANDC__
|
883
|
+
#pragma option pop
|
884
|
+
#endif
|
885
|
+
#ifdef BOOST_MSVC
|
886
|
+
#pragma warning(pop)
|
887
|
+
#endif
|
888
|
+
}
|
889
|
+
|
890
|
+
template <class BidiIterator, class Allocator, class traits>
|
891
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
|
892
|
+
{
|
893
|
+
BOOST_ASSERT(pstate->type == syntax_element_recurse);
|
894
|
+
//
|
895
|
+
// Backup call stack:
|
896
|
+
//
|
897
|
+
push_recursion_pop();
|
898
|
+
//
|
899
|
+
// Set new call stack:
|
900
|
+
//
|
901
|
+
if(recursion_stack.capacity() == 0)
|
902
|
+
{
|
903
|
+
recursion_stack.reserve(50);
|
904
|
+
}
|
905
|
+
recursion_stack.push_back(recursion_info<results_type>());
|
906
|
+
recursion_stack.back().preturn_address = pstate->next.p;
|
907
|
+
recursion_stack.back().results = *m_presult;
|
908
|
+
if(static_cast<const re_recurse*>(pstate)->state_id > 0)
|
909
|
+
{
|
910
|
+
push_repeater_count(static_cast<const re_recurse*>(pstate)->state_id, &next_count);
|
911
|
+
}
|
912
|
+
pstate = static_cast<const re_jump*>(pstate)->alt.p;
|
913
|
+
recursion_stack.back().idx = static_cast<const re_brace*>(pstate)->index;
|
914
|
+
|
915
|
+
return true;
|
916
|
+
}
|
917
|
+
|
918
|
+
template <class BidiIterator, class Allocator, class traits>
|
919
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
|
920
|
+
{
|
921
|
+
int index = static_cast<const re_brace*>(pstate)->index;
|
922
|
+
icase = static_cast<const re_brace*>(pstate)->icase;
|
923
|
+
if(index > 0)
|
924
|
+
{
|
925
|
+
if((m_match_flags & match_nosubs) == 0)
|
926
|
+
{
|
927
|
+
m_presult->set_second(position, index);
|
928
|
+
}
|
929
|
+
if(!recursion_stack.empty())
|
930
|
+
{
|
931
|
+
if(index == recursion_stack.back().idx)
|
932
|
+
{
|
933
|
+
pstate = recursion_stack.back().preturn_address;
|
934
|
+
*m_presult = recursion_stack.back().results;
|
935
|
+
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results);
|
936
|
+
recursion_stack.pop_back();
|
937
|
+
}
|
938
|
+
}
|
939
|
+
}
|
940
|
+
else if((index < 0) && (index != -4))
|
941
|
+
{
|
942
|
+
// matched forward lookahead:
|
943
|
+
pstate = 0;
|
944
|
+
return true;
|
945
|
+
}
|
946
|
+
pstate = pstate->next.p;
|
947
|
+
return true;
|
948
|
+
}
|
949
|
+
|
950
|
+
template <class BidiIterator, class Allocator, class traits>
|
951
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
|
952
|
+
{
|
953
|
+
if(!recursion_stack.empty())
|
954
|
+
{
|
955
|
+
BOOST_ASSERT(0 == recursion_stack.back().idx);
|
956
|
+
pstate = recursion_stack.back().preturn_address;
|
957
|
+
*m_presult = recursion_stack.back().results;
|
958
|
+
push_recursion(recursion_stack.back().idx, recursion_stack.back().preturn_address, &recursion_stack.back().results);
|
959
|
+
recursion_stack.pop_back();
|
960
|
+
return true;
|
961
|
+
}
|
962
|
+
if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
|
963
|
+
return false;
|
964
|
+
if((m_match_flags & match_all) && (position != last))
|
965
|
+
return false;
|
966
|
+
if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
|
967
|
+
return false;
|
968
|
+
m_presult->set_second(position);
|
969
|
+
pstate = 0;
|
970
|
+
m_has_found_match = true;
|
971
|
+
if((m_match_flags & match_posix) == match_posix)
|
972
|
+
{
|
973
|
+
m_result.maybe_assign(*m_presult);
|
974
|
+
if((m_match_flags & match_any) == 0)
|
975
|
+
return false;
|
976
|
+
}
|
977
|
+
#ifdef BOOST_REGEX_MATCH_EXTRA
|
978
|
+
if(match_extra & m_match_flags)
|
979
|
+
{
|
980
|
+
for(unsigned i = 0; i < m_presult->size(); ++i)
|
981
|
+
if((*m_presult)[i].matched)
|
982
|
+
((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
|
983
|
+
}
|
984
|
+
#endif
|
985
|
+
return true;
|
986
|
+
}
|
987
|
+
|
988
|
+
/****************************************************************************
|
989
|
+
|
990
|
+
Unwind and associated proceedures follow, these perform what normal stack
|
991
|
+
unwinding does in the recursive implementation.
|
992
|
+
|
993
|
+
****************************************************************************/
|
994
|
+
|
995
|
+
template <class BidiIterator, class Allocator, class traits>
|
996
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
|
997
|
+
{
|
998
|
+
static unwind_proc_type const s_unwind_table[18] =
|
999
|
+
{
|
1000
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_end,
|
1001
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,
|
1002
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,
|
1003
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,
|
1004
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,
|
1005
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,
|
1006
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,
|
1007
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,
|
1008
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,
|
1009
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,
|
1010
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,
|
1011
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,
|
1012
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,
|
1013
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,
|
1014
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,
|
1015
|
+
&perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,
|
1016
|
+
};
|
1017
|
+
|
1018
|
+
m_recursive_result = have_match;
|
1019
|
+
unwind_proc_type unwinder;
|
1020
|
+
bool cont;
|
1021
|
+
//
|
1022
|
+
// keep unwinding our stack until we have something to do:
|
1023
|
+
//
|
1024
|
+
do
|
1025
|
+
{
|
1026
|
+
unwinder = s_unwind_table[m_backup_state->state_id];
|
1027
|
+
cont = (this->*unwinder)(m_recursive_result);
|
1028
|
+
}while(cont);
|
1029
|
+
//
|
1030
|
+
// return true if we have more states to try:
|
1031
|
+
//
|
1032
|
+
return pstate ? true : false;
|
1033
|
+
}
|
1034
|
+
|
1035
|
+
template <class BidiIterator, class Allocator, class traits>
|
1036
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)
|
1037
|
+
{
|
1038
|
+
pstate = 0; // nothing left to search
|
1039
|
+
return false; // end of stack nothing more to search
|
1040
|
+
}
|
1041
|
+
|
1042
|
+
template <class BidiIterator, class Allocator, class traits>
|
1043
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)
|
1044
|
+
{
|
1045
|
+
saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
|
1046
|
+
// restore previous values if no match was found:
|
1047
|
+
if(have_match == false)
|
1048
|
+
{
|
1049
|
+
m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);
|
1050
|
+
m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);
|
1051
|
+
}
|
1052
|
+
#ifdef BOOST_REGEX_MATCH_EXTRA
|
1053
|
+
//
|
1054
|
+
// we have a match, push the capture information onto the stack:
|
1055
|
+
//
|
1056
|
+
else if(pmp->sub.matched && (match_extra & m_match_flags))
|
1057
|
+
((*m_presult)[pmp->index]).get_captures().push_back(pmp->sub);
|
1058
|
+
#endif
|
1059
|
+
// unwind stack:
|
1060
|
+
m_backup_state = pmp+1;
|
1061
|
+
boost::re_detail::inplace_destroy(pmp);
|
1062
|
+
return true; // keep looking
|
1063
|
+
}
|
1064
|
+
|
1065
|
+
template <class BidiIterator, class Allocator, class traits>
|
1066
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)
|
1067
|
+
{
|
1068
|
+
boost::re_detail::inplace_destroy(m_backup_state++);
|
1069
|
+
pstate = 0; // nothing left to search
|
1070
|
+
return false; // end of stack nothing more to search
|
1071
|
+
}
|
1072
|
+
|
1073
|
+
template <class BidiIterator, class Allocator, class traits>
|
1074
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)
|
1075
|
+
{
|
1076
|
+
saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
|
1077
|
+
pstate = pmp->pstate;
|
1078
|
+
position = pmp->position;
|
1079
|
+
bool result = (r == pmp->positive);
|
1080
|
+
m_recursive_result = pmp->positive ? r : !r;
|
1081
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1082
|
+
m_backup_state = pmp;
|
1083
|
+
return !result; // return false if the assertion was matched to stop search.
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
template <class BidiIterator, class Allocator, class traits>
|
1087
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)
|
1088
|
+
{
|
1089
|
+
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
1090
|
+
if(!r)
|
1091
|
+
{
|
1092
|
+
pstate = pmp->pstate;
|
1093
|
+
position = pmp->position;
|
1094
|
+
}
|
1095
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1096
|
+
m_backup_state = pmp;
|
1097
|
+
return r;
|
1098
|
+
}
|
1099
|
+
|
1100
|
+
template <class BidiIterator, class Allocator, class traits>
|
1101
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)
|
1102
|
+
{
|
1103
|
+
saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
|
1104
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1105
|
+
m_backup_state = pmp;
|
1106
|
+
return true; // keep looking
|
1107
|
+
}
|
1108
|
+
|
1109
|
+
template <class BidiIterator, class Allocator, class traits>
|
1110
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)
|
1111
|
+
{
|
1112
|
+
saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);
|
1113
|
+
void* condemmed = m_stack_base;
|
1114
|
+
m_stack_base = pmp->base;
|
1115
|
+
m_backup_state = pmp->end;
|
1116
|
+
boost::re_detail::inplace_destroy(pmp);
|
1117
|
+
put_mem_block(condemmed);
|
1118
|
+
return true; // keep looking
|
1119
|
+
}
|
1120
|
+
|
1121
|
+
template <class BidiIterator, class Allocator, class traits>
|
1122
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()
|
1123
|
+
{
|
1124
|
+
saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1125
|
+
boost::re_detail::inplace_destroy(p++);
|
1126
|
+
m_backup_state = p;
|
1127
|
+
}
|
1128
|
+
|
1129
|
+
template <class BidiIterator, class Allocator, class traits>
|
1130
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)
|
1131
|
+
{
|
1132
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1133
|
+
|
1134
|
+
// if we have a match, just discard this state:
|
1135
|
+
if(r)
|
1136
|
+
{
|
1137
|
+
destroy_single_repeat();
|
1138
|
+
return true;
|
1139
|
+
}
|
1140
|
+
|
1141
|
+
const re_repeat* rep = pmp->rep;
|
1142
|
+
std::size_t count = pmp->count;
|
1143
|
+
BOOST_ASSERT(rep->next.p != 0);
|
1144
|
+
BOOST_ASSERT(rep->alt.p != 0);
|
1145
|
+
|
1146
|
+
count -= rep->min;
|
1147
|
+
|
1148
|
+
if((m_match_flags & match_partial) && (position == last))
|
1149
|
+
m_has_partial_match = true;
|
1150
|
+
|
1151
|
+
BOOST_ASSERT(count);
|
1152
|
+
position = pmp->last_position;
|
1153
|
+
|
1154
|
+
// backtrack till we can skip out:
|
1155
|
+
do
|
1156
|
+
{
|
1157
|
+
--position;
|
1158
|
+
--count;
|
1159
|
+
++state_count;
|
1160
|
+
}while(count && !can_start(*position, rep->_map, mask_skip));
|
1161
|
+
|
1162
|
+
// if we've hit base, destroy this state:
|
1163
|
+
if(count == 0)
|
1164
|
+
{
|
1165
|
+
destroy_single_repeat();
|
1166
|
+
if(!can_start(*position, rep->_map, mask_skip))
|
1167
|
+
return true;
|
1168
|
+
}
|
1169
|
+
else
|
1170
|
+
{
|
1171
|
+
pmp->count = count + rep->min;
|
1172
|
+
pmp->last_position = position;
|
1173
|
+
}
|
1174
|
+
pstate = rep->alt.p;
|
1175
|
+
return false;
|
1176
|
+
}
|
1177
|
+
|
1178
|
+
template <class BidiIterator, class Allocator, class traits>
|
1179
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)
|
1180
|
+
{
|
1181
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1182
|
+
|
1183
|
+
// if we have a match, just discard this state:
|
1184
|
+
if(r)
|
1185
|
+
{
|
1186
|
+
destroy_single_repeat();
|
1187
|
+
return true;
|
1188
|
+
}
|
1189
|
+
|
1190
|
+
const re_repeat* rep = pmp->rep;
|
1191
|
+
std::size_t count = pmp->count;
|
1192
|
+
BOOST_ASSERT(rep->type == syntax_element_dot_rep);
|
1193
|
+
BOOST_ASSERT(rep->next.p != 0);
|
1194
|
+
BOOST_ASSERT(rep->alt.p != 0);
|
1195
|
+
BOOST_ASSERT(rep->next.p->type == syntax_element_wild);
|
1196
|
+
|
1197
|
+
BOOST_ASSERT(count < rep->max);
|
1198
|
+
pstate = rep->next.p;
|
1199
|
+
position = pmp->last_position;
|
1200
|
+
|
1201
|
+
if(position != last)
|
1202
|
+
{
|
1203
|
+
// wind forward until we can skip out of the repeat:
|
1204
|
+
do
|
1205
|
+
{
|
1206
|
+
if(!match_wild())
|
1207
|
+
{
|
1208
|
+
// failed repeat match, discard this state and look for another:
|
1209
|
+
destroy_single_repeat();
|
1210
|
+
return true;
|
1211
|
+
}
|
1212
|
+
++count;
|
1213
|
+
++state_count;
|
1214
|
+
pstate = rep->next.p;
|
1215
|
+
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
|
1216
|
+
}
|
1217
|
+
if(position == last)
|
1218
|
+
{
|
1219
|
+
// can't repeat any more, remove the pushed state:
|
1220
|
+
destroy_single_repeat();
|
1221
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
1222
|
+
m_has_partial_match = true;
|
1223
|
+
if(0 == (rep->can_be_null & mask_skip))
|
1224
|
+
return true;
|
1225
|
+
}
|
1226
|
+
else if(count == rep->max)
|
1227
|
+
{
|
1228
|
+
// can't repeat any more, remove the pushed state:
|
1229
|
+
destroy_single_repeat();
|
1230
|
+
if(!can_start(*position, rep->_map, mask_skip))
|
1231
|
+
return true;
|
1232
|
+
}
|
1233
|
+
else
|
1234
|
+
{
|
1235
|
+
pmp->count = count;
|
1236
|
+
pmp->last_position = position;
|
1237
|
+
}
|
1238
|
+
pstate = rep->alt.p;
|
1239
|
+
return false;
|
1240
|
+
}
|
1241
|
+
|
1242
|
+
template <class BidiIterator, class Allocator, class traits>
|
1243
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)
|
1244
|
+
{
|
1245
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1246
|
+
|
1247
|
+
// if we have a match, just discard this state:
|
1248
|
+
if(r)
|
1249
|
+
{
|
1250
|
+
destroy_single_repeat();
|
1251
|
+
return true;
|
1252
|
+
}
|
1253
|
+
|
1254
|
+
const re_repeat* rep = pmp->rep;
|
1255
|
+
std::size_t count = pmp->count;
|
1256
|
+
|
1257
|
+
BOOST_ASSERT(count < rep->max);
|
1258
|
+
position = pmp->last_position;
|
1259
|
+
if(position != last)
|
1260
|
+
{
|
1261
|
+
|
1262
|
+
// wind forward until we can skip out of the repeat:
|
1263
|
+
do
|
1264
|
+
{
|
1265
|
+
++position;
|
1266
|
+
++count;
|
1267
|
+
++state_count;
|
1268
|
+
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
|
1269
|
+
}
|
1270
|
+
|
1271
|
+
// remember where we got to if this is a leading repeat:
|
1272
|
+
if((rep->leading) && (count < rep->max))
|
1273
|
+
restart = position;
|
1274
|
+
if(position == last)
|
1275
|
+
{
|
1276
|
+
// can't repeat any more, remove the pushed state:
|
1277
|
+
destroy_single_repeat();
|
1278
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
1279
|
+
m_has_partial_match = true;
|
1280
|
+
if(0 == (rep->can_be_null & mask_skip))
|
1281
|
+
return true;
|
1282
|
+
}
|
1283
|
+
else if(count == rep->max)
|
1284
|
+
{
|
1285
|
+
// can't repeat any more, remove the pushed state:
|
1286
|
+
destroy_single_repeat();
|
1287
|
+
if(!can_start(*position, rep->_map, mask_skip))
|
1288
|
+
return true;
|
1289
|
+
}
|
1290
|
+
else
|
1291
|
+
{
|
1292
|
+
pmp->count = count;
|
1293
|
+
pmp->last_position = position;
|
1294
|
+
}
|
1295
|
+
pstate = rep->alt.p;
|
1296
|
+
return false;
|
1297
|
+
}
|
1298
|
+
|
1299
|
+
template <class BidiIterator, class Allocator, class traits>
|
1300
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)
|
1301
|
+
{
|
1302
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1303
|
+
|
1304
|
+
// if we have a match, just discard this state:
|
1305
|
+
if(r)
|
1306
|
+
{
|
1307
|
+
destroy_single_repeat();
|
1308
|
+
return true;
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
const re_repeat* rep = pmp->rep;
|
1312
|
+
std::size_t count = pmp->count;
|
1313
|
+
pstate = rep->next.p;
|
1314
|
+
const char_type what = *reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
|
1315
|
+
position = pmp->last_position;
|
1316
|
+
|
1317
|
+
BOOST_ASSERT(rep->type == syntax_element_char_rep);
|
1318
|
+
BOOST_ASSERT(rep->next.p != 0);
|
1319
|
+
BOOST_ASSERT(rep->alt.p != 0);
|
1320
|
+
BOOST_ASSERT(rep->next.p->type == syntax_element_literal);
|
1321
|
+
BOOST_ASSERT(count < rep->max);
|
1322
|
+
|
1323
|
+
if(position != last)
|
1324
|
+
{
|
1325
|
+
// wind forward until we can skip out of the repeat:
|
1326
|
+
do
|
1327
|
+
{
|
1328
|
+
if(traits_inst.translate(*position, icase) != what)
|
1329
|
+
{
|
1330
|
+
// failed repeat match, discard this state and look for another:
|
1331
|
+
destroy_single_repeat();
|
1332
|
+
return true;
|
1333
|
+
}
|
1334
|
+
++count;
|
1335
|
+
++ position;
|
1336
|
+
++state_count;
|
1337
|
+
pstate = rep->next.p;
|
1338
|
+
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
|
1339
|
+
}
|
1340
|
+
// remember where we got to if this is a leading repeat:
|
1341
|
+
if((rep->leading) && (count < rep->max))
|
1342
|
+
restart = position;
|
1343
|
+
if(position == last)
|
1344
|
+
{
|
1345
|
+
// can't repeat any more, remove the pushed state:
|
1346
|
+
destroy_single_repeat();
|
1347
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
1348
|
+
m_has_partial_match = true;
|
1349
|
+
if(0 == (rep->can_be_null & mask_skip))
|
1350
|
+
return true;
|
1351
|
+
}
|
1352
|
+
else if(count == rep->max)
|
1353
|
+
{
|
1354
|
+
// can't repeat any more, remove the pushed state:
|
1355
|
+
destroy_single_repeat();
|
1356
|
+
if(!can_start(*position, rep->_map, mask_skip))
|
1357
|
+
return true;
|
1358
|
+
}
|
1359
|
+
else
|
1360
|
+
{
|
1361
|
+
pmp->count = count;
|
1362
|
+
pmp->last_position = position;
|
1363
|
+
}
|
1364
|
+
pstate = rep->alt.p;
|
1365
|
+
return false;
|
1366
|
+
}
|
1367
|
+
|
1368
|
+
template <class BidiIterator, class Allocator, class traits>
|
1369
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)
|
1370
|
+
{
|
1371
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1372
|
+
|
1373
|
+
// if we have a match, just discard this state:
|
1374
|
+
if(r)
|
1375
|
+
{
|
1376
|
+
destroy_single_repeat();
|
1377
|
+
return true;
|
1378
|
+
}
|
1379
|
+
|
1380
|
+
const re_repeat* rep = pmp->rep;
|
1381
|
+
std::size_t count = pmp->count;
|
1382
|
+
pstate = rep->next.p;
|
1383
|
+
const unsigned char* map = static_cast<const re_set*>(rep->next.p)->_map;
|
1384
|
+
position = pmp->last_position;
|
1385
|
+
|
1386
|
+
BOOST_ASSERT(rep->type == syntax_element_short_set_rep);
|
1387
|
+
BOOST_ASSERT(rep->next.p != 0);
|
1388
|
+
BOOST_ASSERT(rep->alt.p != 0);
|
1389
|
+
BOOST_ASSERT(rep->next.p->type == syntax_element_set);
|
1390
|
+
BOOST_ASSERT(count < rep->max);
|
1391
|
+
|
1392
|
+
if(position != last)
|
1393
|
+
{
|
1394
|
+
// wind forward until we can skip out of the repeat:
|
1395
|
+
do
|
1396
|
+
{
|
1397
|
+
if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
|
1398
|
+
{
|
1399
|
+
// failed repeat match, discard this state and look for another:
|
1400
|
+
destroy_single_repeat();
|
1401
|
+
return true;
|
1402
|
+
}
|
1403
|
+
++count;
|
1404
|
+
++ position;
|
1405
|
+
++state_count;
|
1406
|
+
pstate = rep->next.p;
|
1407
|
+
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
|
1408
|
+
}
|
1409
|
+
// remember where we got to if this is a leading repeat:
|
1410
|
+
if((rep->leading) && (count < rep->max))
|
1411
|
+
restart = position;
|
1412
|
+
if(position == last)
|
1413
|
+
{
|
1414
|
+
// can't repeat any more, remove the pushed state:
|
1415
|
+
destroy_single_repeat();
|
1416
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
1417
|
+
m_has_partial_match = true;
|
1418
|
+
if(0 == (rep->can_be_null & mask_skip))
|
1419
|
+
return true;
|
1420
|
+
}
|
1421
|
+
else if(count == rep->max)
|
1422
|
+
{
|
1423
|
+
// can't repeat any more, remove the pushed state:
|
1424
|
+
destroy_single_repeat();
|
1425
|
+
if(!can_start(*position, rep->_map, mask_skip))
|
1426
|
+
return true;
|
1427
|
+
}
|
1428
|
+
else
|
1429
|
+
{
|
1430
|
+
pmp->count = count;
|
1431
|
+
pmp->last_position = position;
|
1432
|
+
}
|
1433
|
+
pstate = rep->alt.p;
|
1434
|
+
return false;
|
1435
|
+
}
|
1436
|
+
|
1437
|
+
template <class BidiIterator, class Allocator, class traits>
|
1438
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)
|
1439
|
+
{
|
1440
|
+
typedef typename traits::char_class_type m_type;
|
1441
|
+
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
|
1442
|
+
|
1443
|
+
// if we have a match, just discard this state:
|
1444
|
+
if(r)
|
1445
|
+
{
|
1446
|
+
destroy_single_repeat();
|
1447
|
+
return true;
|
1448
|
+
}
|
1449
|
+
|
1450
|
+
const re_repeat* rep = pmp->rep;
|
1451
|
+
std::size_t count = pmp->count;
|
1452
|
+
pstate = rep->next.p;
|
1453
|
+
const re_set_long<m_type>* set = static_cast<const re_set_long<m_type>*>(pstate);
|
1454
|
+
position = pmp->last_position;
|
1455
|
+
|
1456
|
+
BOOST_ASSERT(rep->type == syntax_element_long_set_rep);
|
1457
|
+
BOOST_ASSERT(rep->next.p != 0);
|
1458
|
+
BOOST_ASSERT(rep->alt.p != 0);
|
1459
|
+
BOOST_ASSERT(rep->next.p->type == syntax_element_long_set);
|
1460
|
+
BOOST_ASSERT(count < rep->max);
|
1461
|
+
|
1462
|
+
if(position != last)
|
1463
|
+
{
|
1464
|
+
// wind forward until we can skip out of the repeat:
|
1465
|
+
do
|
1466
|
+
{
|
1467
|
+
if(position == re_is_set_member(position, last, set, re.get_data(), icase))
|
1468
|
+
{
|
1469
|
+
// failed repeat match, discard this state and look for another:
|
1470
|
+
destroy_single_repeat();
|
1471
|
+
return true;
|
1472
|
+
}
|
1473
|
+
++position;
|
1474
|
+
++count;
|
1475
|
+
++state_count;
|
1476
|
+
pstate = rep->next.p;
|
1477
|
+
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
|
1478
|
+
}
|
1479
|
+
// remember where we got to if this is a leading repeat:
|
1480
|
+
if((rep->leading) && (count < rep->max))
|
1481
|
+
restart = position;
|
1482
|
+
if(position == last)
|
1483
|
+
{
|
1484
|
+
// can't repeat any more, remove the pushed state:
|
1485
|
+
destroy_single_repeat();
|
1486
|
+
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
|
1487
|
+
m_has_partial_match = true;
|
1488
|
+
if(0 == (rep->can_be_null & mask_skip))
|
1489
|
+
return true;
|
1490
|
+
}
|
1491
|
+
else if(count == rep->max)
|
1492
|
+
{
|
1493
|
+
// can't repeat any more, remove the pushed state:
|
1494
|
+
destroy_single_repeat();
|
1495
|
+
if(!can_start(*position, rep->_map, mask_skip))
|
1496
|
+
return true;
|
1497
|
+
}
|
1498
|
+
else
|
1499
|
+
{
|
1500
|
+
pmp->count = count;
|
1501
|
+
pmp->last_position = position;
|
1502
|
+
}
|
1503
|
+
pstate = rep->alt.p;
|
1504
|
+
return false;
|
1505
|
+
}
|
1506
|
+
|
1507
|
+
template <class BidiIterator, class Allocator, class traits>
|
1508
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)
|
1509
|
+
{
|
1510
|
+
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
1511
|
+
if(!r)
|
1512
|
+
{
|
1513
|
+
position = pmp->position;
|
1514
|
+
pstate = pmp->pstate;
|
1515
|
+
++(*next_count);
|
1516
|
+
}
|
1517
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1518
|
+
m_backup_state = pmp;
|
1519
|
+
return r;
|
1520
|
+
}
|
1521
|
+
|
1522
|
+
template <class BidiIterator, class Allocator, class traits>
|
1523
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)
|
1524
|
+
{
|
1525
|
+
saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
|
1526
|
+
if(!r)
|
1527
|
+
{
|
1528
|
+
recursion_stack.push_back(recursion_info<results_type>());
|
1529
|
+
recursion_stack.back().idx = pmp->recursion_id;
|
1530
|
+
recursion_stack.back().preturn_address = pmp->preturn_address;
|
1531
|
+
recursion_stack.back().results = pmp->results;
|
1532
|
+
}
|
1533
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1534
|
+
m_backup_state = pmp;
|
1535
|
+
return true;
|
1536
|
+
}
|
1537
|
+
|
1538
|
+
template <class BidiIterator, class Allocator, class traits>
|
1539
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)
|
1540
|
+
{
|
1541
|
+
saved_state* pmp = static_cast<saved_state*>(m_backup_state);
|
1542
|
+
if(!r)
|
1543
|
+
{
|
1544
|
+
recursion_stack.pop_back();
|
1545
|
+
}
|
1546
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1547
|
+
m_backup_state = pmp;
|
1548
|
+
return true;
|
1549
|
+
}
|
1550
|
+
|
1551
|
+
template <class BidiIterator, class Allocator, class traits>
|
1552
|
+
void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()
|
1553
|
+
{
|
1554
|
+
saved_state* pmp = static_cast<saved_state*>(m_backup_state);
|
1555
|
+
--pmp;
|
1556
|
+
if(pmp < m_stack_base)
|
1557
|
+
{
|
1558
|
+
extend_stack();
|
1559
|
+
pmp = static_cast<saved_state*>(m_backup_state);
|
1560
|
+
--pmp;
|
1561
|
+
}
|
1562
|
+
(void) new (pmp)saved_state(15);
|
1563
|
+
m_backup_state = pmp;
|
1564
|
+
}
|
1565
|
+
/*
|
1566
|
+
template <class BidiIterator, class Allocator, class traits>
|
1567
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_pop(bool r)
|
1568
|
+
{
|
1569
|
+
saved_state* pmp = static_cast<saved_state*>(m_backup_state);
|
1570
|
+
if(!r)
|
1571
|
+
{
|
1572
|
+
--parenthesis_stack_position;
|
1573
|
+
}
|
1574
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1575
|
+
m_backup_state = pmp;
|
1576
|
+
return true;
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
template <class BidiIterator, class Allocator, class traits>
|
1580
|
+
void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_pop()
|
1581
|
+
{
|
1582
|
+
saved_state* pmp = static_cast<saved_state*>(m_backup_state);
|
1583
|
+
--pmp;
|
1584
|
+
if(pmp < m_stack_base)
|
1585
|
+
{
|
1586
|
+
extend_stack();
|
1587
|
+
pmp = static_cast<saved_state*>(m_backup_state);
|
1588
|
+
--pmp;
|
1589
|
+
}
|
1590
|
+
(void) new (pmp)saved_state(16);
|
1591
|
+
m_backup_state = pmp;
|
1592
|
+
}
|
1593
|
+
|
1594
|
+
template <class BidiIterator, class Allocator, class traits>
|
1595
|
+
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_push(bool r)
|
1596
|
+
{
|
1597
|
+
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
1598
|
+
if(!r)
|
1599
|
+
{
|
1600
|
+
parenthesis_stack[parenthesis_stack_position++] = pmp->position;
|
1601
|
+
}
|
1602
|
+
boost::re_detail::inplace_destroy(pmp++);
|
1603
|
+
m_backup_state = pmp;
|
1604
|
+
return true;
|
1605
|
+
}
|
1606
|
+
|
1607
|
+
template <class BidiIterator, class Allocator, class traits>
|
1608
|
+
inline void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_push(BidiIterator p)
|
1609
|
+
{
|
1610
|
+
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
1611
|
+
--pmp;
|
1612
|
+
if(pmp < m_stack_base)
|
1613
|
+
{
|
1614
|
+
extend_stack();
|
1615
|
+
pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
1616
|
+
--pmp;
|
1617
|
+
}
|
1618
|
+
(void) new (pmp)saved_position<BidiIterator>(0, p, 17);
|
1619
|
+
m_backup_state = pmp;
|
1620
|
+
}
|
1621
|
+
*/
|
1622
|
+
} // namespace re_detail
|
1623
|
+
} // namespace boost
|
1624
|
+
|
1625
|
+
#ifdef BOOST_MSVC
|
1626
|
+
# pragma warning(pop)
|
1627
|
+
#endif
|
1628
|
+
|
1629
|
+
#ifdef BOOST_MSVC
|
1630
|
+
#pragma warning(push)
|
1631
|
+
#pragma warning(disable: 4103)
|
1632
|
+
#endif
|
1633
|
+
#ifdef BOOST_HAS_ABI_HEADERS
|
1634
|
+
# include BOOST_ABI_SUFFIX
|
1635
|
+
#endif
|
1636
|
+
#ifdef BOOST_MSVC
|
1637
|
+
#pragma warning(pop)
|
1638
|
+
#endif
|
1639
|
+
|
1640
|
+
#endif
|
1641
|
+
|
1642
|
+
|