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.

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