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,741 @@
1
+ /*
2
+ *
3
+ * Copyright (c) 2004
4
+ * John Maddock
5
+ *
6
+ * Use, modification and distribution are subject to the
7
+ * Boost Software License, Version 1.0. (See accompanying file
8
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9
+ *
10
+ */
11
+
12
+ /*
13
+ * LOCATION: see http://www.boost.org for most recent version.
14
+ * FILE w32_regex_traits.hpp
15
+ * VERSION see <boost/version.hpp>
16
+ * DESCRIPTION: Declares regular expression traits class w32_regex_traits.
17
+ */
18
+
19
+ #ifndef BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
20
+ #define BOOST_W32_REGEX_TRAITS_HPP_INCLUDED
21
+
22
+ #ifndef BOOST_RE_PAT_EXCEPT_HPP
23
+ #include <boost/regex/pattern_except.hpp>
24
+ #endif
25
+ #ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
26
+ #include <boost/regex/v4/regex_traits_defaults.hpp>
27
+ #endif
28
+ #ifdef BOOST_HAS_THREADS
29
+ #include <boost/regex/pending/static_mutex.hpp>
30
+ #endif
31
+ #ifndef BOOST_REGEX_PRIMARY_TRANSFORM
32
+ #include <boost/regex/v4/primary_transform.hpp>
33
+ #endif
34
+ #ifndef BOOST_REGEX_OBJECT_CACHE_HPP
35
+ #include <boost/regex/pending/object_cache.hpp>
36
+ #endif
37
+
38
+ #ifdef BOOST_MSVC
39
+ #pragma warning(push)
40
+ #pragma warning(disable: 4103)
41
+ #endif
42
+ #ifdef BOOST_HAS_ABI_HEADERS
43
+ # include BOOST_ABI_PREFIX
44
+ #endif
45
+ #ifdef BOOST_MSVC
46
+ #pragma warning(pop)
47
+ #endif
48
+
49
+ #ifdef BOOST_MSVC
50
+ #pragma warning(push)
51
+ #pragma warning(disable:4786)
52
+ #pragma warning(disable:4800)
53
+ #endif
54
+
55
+ namespace boost{
56
+
57
+ //
58
+ // forward declaration is needed by some compilers:
59
+ //
60
+ template <class charT>
61
+ class w32_regex_traits;
62
+
63
+ namespace re_detail{
64
+
65
+ //
66
+ // start by typedeffing the types we'll need:
67
+ //
68
+ typedef ::boost::uint32_t lcid_type; // placeholder for LCID.
69
+ typedef ::boost::shared_ptr<void> cat_type; // placeholder for dll HANDLE.
70
+
71
+ //
72
+ // then add wrappers around the actual Win32 API's (ie implementation hiding):
73
+ //
74
+ BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale();
75
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(char, lcid_type);
76
+ #ifndef BOOST_NO_WREGEX
77
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(wchar_t, lcid_type);
78
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
79
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_lower(unsigned short ca, lcid_type state_id);
80
+ #endif
81
+ #endif
82
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(char, lcid_type);
83
+ #ifndef BOOST_NO_WREGEX
84
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(wchar_t, lcid_type);
85
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
86
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is_upper(unsigned short ca, lcid_type state_id);
87
+ #endif
88
+ #endif
89
+ BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name);
90
+ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::string& def);
91
+ #ifndef BOOST_NO_WREGEX
92
+ BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type state_id, int i, const std::wstring& def);
93
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
94
+ BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::basic_string<unsigned short>& def);
95
+ #endif
96
+ #endif
97
+ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type state_id, const char* p1, const char* p2);
98
+ #ifndef BOOST_NO_WREGEX
99
+ BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type state_id, const wchar_t* p1, const wchar_t* p2);
100
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
101
+ BOOST_REGEX_DECL std::basic_string<unsigned short> BOOST_REGEX_CALL w32_transform(lcid_type state_id, const unsigned short* p1, const unsigned short* p2);
102
+ #endif
103
+ #endif
104
+ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_tolower(char c, lcid_type);
105
+ #ifndef BOOST_NO_WREGEX
106
+ BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_tolower(wchar_t c, lcid_type);
107
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
108
+ BOOST_REGEX_DECL unsigned short BOOST_REGEX_CALL w32_tolower(unsigned short c, lcid_type state_id);
109
+ #endif
110
+ #endif
111
+ BOOST_REGEX_DECL char BOOST_REGEX_CALL w32_toupper(char c, lcid_type);
112
+ #ifndef BOOST_NO_WREGEX
113
+ BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL w32_toupper(wchar_t c, lcid_type);
114
+ #endif
115
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, char c);
116
+ #ifndef BOOST_NO_WREGEX
117
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type, boost::uint32_t mask, wchar_t c);
118
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
119
+ BOOST_REGEX_DECL bool BOOST_REGEX_CALL w32_is(lcid_type state_id, boost::uint32_t m, unsigned short c);
120
+ #endif
121
+ #endif
122
+ //
123
+ // class w32_regex_traits_base:
124
+ // acts as a container for locale and the facets we are using.
125
+ //
126
+ template <class charT>
127
+ struct w32_regex_traits_base
128
+ {
129
+ w32_regex_traits_base(lcid_type l)
130
+ { imbue(l); }
131
+ lcid_type imbue(lcid_type l);
132
+
133
+ lcid_type m_locale;
134
+ };
135
+
136
+ template <class charT>
137
+ inline lcid_type w32_regex_traits_base<charT>::imbue(lcid_type l)
138
+ {
139
+ lcid_type result(m_locale);
140
+ m_locale = l;
141
+ return result;
142
+ }
143
+
144
+ //
145
+ // class w32_regex_traits_char_layer:
146
+ // implements methods that require specialisation for narrow characters:
147
+ //
148
+ template <class charT>
149
+ class w32_regex_traits_char_layer : public w32_regex_traits_base<charT>
150
+ {
151
+ typedef std::basic_string<charT> string_type;
152
+ typedef std::map<charT, regex_constants::syntax_type> map_type;
153
+ typedef typename map_type::const_iterator map_iterator_type;
154
+ public:
155
+ w32_regex_traits_char_layer(const lcid_type l);
156
+
157
+ regex_constants::syntax_type syntax_type(charT c)const
158
+ {
159
+ map_iterator_type i = m_char_map.find(c);
160
+ return ((i == m_char_map.end()) ? 0 : i->second);
161
+ }
162
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
163
+ {
164
+ map_iterator_type i = m_char_map.find(c);
165
+ if(i == m_char_map.end())
166
+ {
167
+ if(::boost::re_detail::w32_is_lower(c, this->m_locale)) return regex_constants::escape_type_class;
168
+ if(::boost::re_detail::w32_is_upper(c, this->m_locale)) return regex_constants::escape_type_not_class;
169
+ return 0;
170
+ }
171
+ return i->second;
172
+ }
173
+ charT tolower(charT c)const
174
+ {
175
+ return ::boost::re_detail::w32_tolower(c, this->m_locale);
176
+ }
177
+ bool isctype(boost::uint32_t mask, charT c)const
178
+ {
179
+ return ::boost::re_detail::w32_is(this->m_locale, mask, c);
180
+ }
181
+
182
+ private:
183
+ string_type get_default_message(regex_constants::syntax_type);
184
+ // TODO: use a hash table when available!
185
+ map_type m_char_map;
186
+ };
187
+
188
+ template <class charT>
189
+ w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
190
+ : w32_regex_traits_base<charT>(l)
191
+ {
192
+ // we need to start by initialising our syntax map so we know which
193
+ // character is used for which purpose:
194
+ cat_type cat;
195
+ std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
196
+ if(cat_name.size())
197
+ {
198
+ cat = ::boost::re_detail::w32_cat_open(cat_name);
199
+ if(!cat)
200
+ {
201
+ std::string m("Unable to open message catalog: ");
202
+ std::runtime_error err(m + cat_name);
203
+ boost::re_detail::raise_runtime_error(err);
204
+ }
205
+ }
206
+ //
207
+ // if we have a valid catalog then load our messages:
208
+ //
209
+ if(cat)
210
+ {
211
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
212
+ {
213
+ string_type mss = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i, get_default_message(i));
214
+ for(typename string_type::size_type j = 0; j < mss.size(); ++j)
215
+ {
216
+ this->m_char_map[mss[j]] = i;
217
+ }
218
+ }
219
+ }
220
+ else
221
+ {
222
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
223
+ {
224
+ const char* ptr = get_default_syntax(i);
225
+ while(ptr && *ptr)
226
+ {
227
+ this->m_char_map[static_cast<charT>(*ptr)] = i;
228
+ ++ptr;
229
+ }
230
+ }
231
+ }
232
+ }
233
+
234
+ template <class charT>
235
+ typename w32_regex_traits_char_layer<charT>::string_type
236
+ w32_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
237
+ {
238
+ const char* ptr = get_default_syntax(i);
239
+ string_type result;
240
+ while(ptr && *ptr)
241
+ {
242
+ result.append(1, static_cast<charT>(*ptr));
243
+ ++ptr;
244
+ }
245
+ return result;
246
+ }
247
+
248
+ //
249
+ // specialised version for narrow characters:
250
+ //
251
+ template <>
252
+ class BOOST_REGEX_DECL w32_regex_traits_char_layer<char> : public w32_regex_traits_base<char>
253
+ {
254
+ typedef std::string string_type;
255
+ public:
256
+ w32_regex_traits_char_layer(::boost::re_detail::lcid_type l)
257
+ : w32_regex_traits_base<char>(l)
258
+ {
259
+ init();
260
+ }
261
+
262
+ regex_constants::syntax_type syntax_type(char c)const
263
+ {
264
+ return m_char_map[static_cast<unsigned char>(c)];
265
+ }
266
+ regex_constants::escape_syntax_type escape_syntax_type(char c) const
267
+ {
268
+ return m_char_map[static_cast<unsigned char>(c)];
269
+ }
270
+ char tolower(char c)const
271
+ {
272
+ return m_lower_map[static_cast<unsigned char>(c)];
273
+ }
274
+ bool isctype(boost::uint32_t mask, char c)const
275
+ {
276
+ return m_type_map[static_cast<unsigned char>(c)] & mask;
277
+ }
278
+
279
+ private:
280
+ regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
281
+ char m_lower_map[1u << CHAR_BIT];
282
+ boost::uint16_t m_type_map[1u << CHAR_BIT];
283
+ void init();
284
+ };
285
+
286
+ //
287
+ // class w32_regex_traits_implementation:
288
+ // provides pimpl implementation for w32_regex_traits.
289
+ //
290
+ template <class charT>
291
+ class w32_regex_traits_implementation : public w32_regex_traits_char_layer<charT>
292
+ {
293
+ public:
294
+ typedef typename w32_regex_traits<charT>::char_class_type char_class_type;
295
+ BOOST_STATIC_CONSTANT(char_class_type, mask_word = 0x0400); // must be C1_DEFINED << 1
296
+ BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 0x0800); // must be C1_DEFINED << 2
297
+ BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 0x1000); // must be C1_DEFINED << 3
298
+ BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 0x2000); // must be C1_DEFINED << 4
299
+ BOOST_STATIC_CONSTANT(char_class_type, mask_base = 0x3ff); // all the masks used by the CT_CTYPE1 group
300
+
301
+ typedef std::basic_string<charT> string_type;
302
+ typedef charT char_type;
303
+ w32_regex_traits_implementation(::boost::re_detail::lcid_type l);
304
+ std::string error_string(regex_constants::error_type n) const
305
+ {
306
+ if(!m_error_strings.empty())
307
+ {
308
+ std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
309
+ return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
310
+ }
311
+ return get_default_error_string(n);
312
+ }
313
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
314
+ {
315
+ char_class_type result = lookup_classname_imp(p1, p2);
316
+ if(result == 0)
317
+ {
318
+ typedef typename string_type::size_type size_type;
319
+ string_type temp(p1, p2);
320
+ for(size_type i = 0; i < temp.size(); ++i)
321
+ temp[i] = this->tolower(temp[i]);
322
+ result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
323
+ }
324
+ return result;
325
+ }
326
+ string_type lookup_collatename(const charT* p1, const charT* p2) const;
327
+ string_type transform_primary(const charT* p1, const charT* p2) const;
328
+ string_type transform(const charT* p1, const charT* p2) const
329
+ {
330
+ return ::boost::re_detail::w32_transform(this->m_locale, p1, p2);
331
+ }
332
+ private:
333
+ std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
334
+ std::map<string_type, char_class_type> m_custom_class_names; // character class names
335
+ std::map<string_type, string_type> m_custom_collate_names; // collating element names
336
+ unsigned m_collate_type; // the form of the collation string
337
+ charT m_collate_delim; // the collation group delimiter
338
+ //
339
+ // helpers:
340
+ //
341
+ char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
342
+ };
343
+
344
+ template <class charT>
345
+ typename w32_regex_traits_implementation<charT>::string_type
346
+ w32_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
347
+ {
348
+ string_type result;
349
+ //
350
+ // What we do here depends upon the format of the sort key returned by
351
+ // sort key returned by this->transform:
352
+ //
353
+ switch(m_collate_type)
354
+ {
355
+ case sort_C:
356
+ case sort_unknown:
357
+ // the best we can do is translate to lower case, then get a regular sort key:
358
+ {
359
+ result.assign(p1, p2);
360
+ typedef typename string_type::size_type size_type;
361
+ for(size_type i = 0; i < result.size(); ++i)
362
+ result[i] = this->tolower(result[i]);
363
+ result = this->transform(&*result.begin(), &*result.begin() + result.size());
364
+ break;
365
+ }
366
+ case sort_fixed:
367
+ {
368
+ // get a regular sort key, and then truncate it:
369
+ result.assign(this->transform(p1, p2));
370
+ result.erase(this->m_collate_delim);
371
+ break;
372
+ }
373
+ case sort_delim:
374
+ // get a regular sort key, and then truncate everything after the delim:
375
+ result.assign(this->transform(p1, p2));
376
+ std::size_t i;
377
+ for(i = 0; i < result.size(); ++i)
378
+ {
379
+ if(result[i] == m_collate_delim)
380
+ break;
381
+ }
382
+ result.erase(i);
383
+ break;
384
+ }
385
+ if(result.empty())
386
+ result = string_type(1, charT(0));
387
+ return result;
388
+ }
389
+
390
+ template <class charT>
391
+ typename w32_regex_traits_implementation<charT>::string_type
392
+ w32_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
393
+ {
394
+ typedef typename std::map<string_type, string_type>::const_iterator iter_type;
395
+ if(m_custom_collate_names.size())
396
+ {
397
+ iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
398
+ if(pos != m_custom_collate_names.end())
399
+ return pos->second;
400
+ }
401
+ #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
402
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
403
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
404
+ std::string name(p1, p2);
405
+ #else
406
+ std::string name;
407
+ const charT* p0 = p1;
408
+ while(p0 != p2)
409
+ name.append(1, char(*p0++));
410
+ #endif
411
+ name = lookup_default_collate_name(name);
412
+ #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
413
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
414
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
415
+ if(name.size())
416
+ return string_type(name.begin(), name.end());
417
+ #else
418
+ if(name.size())
419
+ {
420
+ string_type result;
421
+ typedef std::string::const_iterator iter;
422
+ iter b = name.begin();
423
+ iter e = name.end();
424
+ while(b != e)
425
+ result.append(1, charT(*b++));
426
+ return result;
427
+ }
428
+ #endif
429
+ if(p2 - p1 == 1)
430
+ return string_type(1, *p1);
431
+ return string_type();
432
+ }
433
+
434
+ template <class charT>
435
+ w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost::re_detail::lcid_type l)
436
+ : w32_regex_traits_char_layer<charT>(l)
437
+ {
438
+ cat_type cat;
439
+ std::string cat_name(w32_regex_traits<charT>::get_catalog_name());
440
+ if(cat_name.size())
441
+ {
442
+ cat = ::boost::re_detail::w32_cat_open(cat_name);
443
+ if(!cat)
444
+ {
445
+ std::string m("Unable to open message catalog: ");
446
+ std::runtime_error err(m + cat_name);
447
+ boost::re_detail::raise_runtime_error(err);
448
+ }
449
+ }
450
+ //
451
+ // if we have a valid catalog then load our messages:
452
+ //
453
+ if(cat)
454
+ {
455
+ //
456
+ // Error messages:
457
+ //
458
+ for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
459
+ i <= boost::regex_constants::error_unknown;
460
+ i = static_cast<boost::regex_constants::error_type>(i + 1))
461
+ {
462
+ const char* p = get_default_error_string(i);
463
+ string_type default_message;
464
+ while(*p)
465
+ {
466
+ default_message.append(1, static_cast<charT>(*p));
467
+ ++p;
468
+ }
469
+ string_type s = ::boost::re_detail::w32_cat_get(cat, this->m_locale, i+200, default_message);
470
+ std::string result;
471
+ for(std::string::size_type j = 0; j < s.size(); ++j)
472
+ {
473
+ result.append(1, static_cast<char>(s[j]));
474
+ }
475
+ m_error_strings[i] = result;
476
+ }
477
+ //
478
+ // Custom class names:
479
+ //
480
+ static const char_class_type masks[14] =
481
+ {
482
+ 0x0104u, // C1_ALPHA | C1_DIGIT
483
+ 0x0100u, // C1_ALPHA
484
+ 0x0020u, // C1_CNTRL
485
+ 0x0004u, // C1_DIGIT
486
+ (~(0x0020u|0x0008u) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE
487
+ 0x0002u, // C1_LOWER
488
+ (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
489
+ 0x0010u, // C1_PUNCT
490
+ 0x0008u, // C1_SPACE
491
+ 0x0001u, // C1_UPPER
492
+ 0x0080u, // C1_XDIGIT
493
+ 0x0040u, // C1_BLANK
494
+ w32_regex_traits_implementation<charT>::mask_word,
495
+ w32_regex_traits_implementation<charT>::mask_unicode,
496
+ };
497
+ static const string_type null_string;
498
+ for(unsigned int j = 0; j <= 13; ++j)
499
+ {
500
+ string_type s(::boost::re_detail::w32_cat_get(cat, this->m_locale, j+300, null_string));
501
+ if(s.size())
502
+ this->m_custom_class_names[s] = masks[j];
503
+ }
504
+ }
505
+ //
506
+ // get the collation format used by m_pcollate:
507
+ //
508
+ m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
509
+ }
510
+
511
+ template <class charT>
512
+ typename w32_regex_traits_implementation<charT>::char_class_type
513
+ w32_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
514
+ {
515
+ static const char_class_type masks[22] =
516
+ {
517
+ 0,
518
+ 0x0104u, // C1_ALPHA | C1_DIGIT
519
+ 0x0100u, // C1_ALPHA
520
+ 0x0040u, // C1_BLANK
521
+ 0x0020u, // C1_CNTRL
522
+ 0x0004u, // C1_DIGIT
523
+ 0x0004u, // C1_DIGIT
524
+ (~(0x0020u|0x0008u|0x0040) & 0x01ffu) | 0x0400u, // not C1_CNTRL or C1_SPACE or C1_BLANK
525
+ w32_regex_traits_implementation<charT>::mask_horizontal,
526
+ 0x0002u, // C1_LOWER
527
+ 0x0002u, // C1_LOWER
528
+ (~0x0020u & 0x01ffu) | 0x0400, // not C1_CNTRL
529
+ 0x0010u, // C1_PUNCT
530
+ 0x0008u, // C1_SPACE
531
+ 0x0008u, // C1_SPACE
532
+ 0x0001u, // C1_UPPER
533
+ w32_regex_traits_implementation<charT>::mask_unicode,
534
+ 0x0001u, // C1_UPPER
535
+ w32_regex_traits_implementation<charT>::mask_vertical,
536
+ 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
537
+ 0x0104u | w32_regex_traits_implementation<charT>::mask_word,
538
+ 0x0080u, // C1_XDIGIT
539
+ };
540
+ if(m_custom_class_names.size())
541
+ {
542
+ typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
543
+ map_iter pos = m_custom_class_names.find(string_type(p1, p2));
544
+ if(pos != m_custom_class_names.end())
545
+ return pos->second;
546
+ }
547
+ std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
548
+ if(state_id < sizeof(masks) / sizeof(masks[0]))
549
+ return masks[state_id];
550
+ return masks[0];
551
+ }
552
+
553
+
554
+ template <class charT>
555
+ boost::shared_ptr<const w32_regex_traits_implementation<charT> > create_w32_regex_traits(::boost::re_detail::lcid_type l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
556
+ {
557
+ // TODO: create a cache for previously constructed objects.
558
+ return boost::object_cache< ::boost::re_detail::lcid_type, w32_regex_traits_implementation<charT> >::get(l, 5);
559
+ }
560
+
561
+ } // re_detail
562
+
563
+ template <class charT>
564
+ class w32_regex_traits
565
+ {
566
+ public:
567
+ typedef charT char_type;
568
+ typedef std::size_t size_type;
569
+ typedef std::basic_string<char_type> string_type;
570
+ typedef ::boost::re_detail::lcid_type locale_type;
571
+ typedef boost::uint_least32_t char_class_type;
572
+
573
+ struct boost_extensions_tag{};
574
+
575
+ w32_regex_traits()
576
+ : m_pimpl(re_detail::create_w32_regex_traits<charT>(::boost::re_detail::w32_get_default_locale()))
577
+ { }
578
+ static size_type length(const char_type* p)
579
+ {
580
+ return std::char_traits<charT>::length(p);
581
+ }
582
+ regex_constants::syntax_type syntax_type(charT c)const
583
+ {
584
+ return m_pimpl->syntax_type(c);
585
+ }
586
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
587
+ {
588
+ return m_pimpl->escape_syntax_type(c);
589
+ }
590
+ charT translate(charT c) const
591
+ {
592
+ return c;
593
+ }
594
+ charT translate_nocase(charT c) const
595
+ {
596
+ return this->m_pimpl->tolower(c);
597
+ }
598
+ charT translate(charT c, bool icase) const
599
+ {
600
+ return icase ? this->m_pimpl->tolower(c) : c;
601
+ }
602
+ charT tolower(charT c) const
603
+ {
604
+ return this->m_pimpl->tolower(c);
605
+ }
606
+ charT toupper(charT c) const
607
+ {
608
+ return ::boost::re_detail::w32_toupper(c, this->m_pimpl->m_locale);
609
+ }
610
+ string_type transform(const charT* p1, const charT* p2) const
611
+ {
612
+ return ::boost::re_detail::w32_transform(this->m_pimpl->m_locale, p1, p2);
613
+ }
614
+ string_type transform_primary(const charT* p1, const charT* p2) const
615
+ {
616
+ return m_pimpl->transform_primary(p1, p2);
617
+ }
618
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
619
+ {
620
+ return m_pimpl->lookup_classname(p1, p2);
621
+ }
622
+ string_type lookup_collatename(const charT* p1, const charT* p2) const
623
+ {
624
+ return m_pimpl->lookup_collatename(p1, p2);
625
+ }
626
+ bool isctype(charT c, char_class_type f) const
627
+ {
628
+ if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base)
629
+ && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
630
+ return true;
631
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
632
+ return true;
633
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_word) && (c == '_'))
634
+ return true;
635
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_vertical)
636
+ && (::boost::re_detail::is_separator(c) || (c == '\v')))
637
+ return true;
638
+ else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_horizontal)
639
+ && this->isctype(c, 0x0008u) && !this->isctype(c, re_detail::w32_regex_traits_implementation<charT>::mask_vertical))
640
+ return true;
641
+ return false;
642
+ }
643
+ int toi(const charT*& p1, const charT* p2, int radix)const
644
+ {
645
+ return ::boost::re_detail::global_toi(p1, p2, radix, *this);
646
+ }
647
+ int value(charT c, int radix)const
648
+ {
649
+ int result = ::boost::re_detail::global_value(c);
650
+ return result < radix ? result : -1;
651
+ }
652
+ locale_type imbue(locale_type l)
653
+ {
654
+ ::boost::re_detail::lcid_type result(getloc());
655
+ m_pimpl = re_detail::create_w32_regex_traits<charT>(l);
656
+ return result;
657
+ }
658
+ locale_type getloc()const
659
+ {
660
+ return m_pimpl->m_locale;
661
+ }
662
+ std::string error_string(regex_constants::error_type n) const
663
+ {
664
+ return m_pimpl->error_string(n);
665
+ }
666
+
667
+ //
668
+ // extension:
669
+ // set the name of the message catalog in use (defaults to "boost_regex").
670
+ //
671
+ static std::string catalog_name(const std::string& name);
672
+ static std::string get_catalog_name();
673
+
674
+ private:
675
+ boost::shared_ptr<const re_detail::w32_regex_traits_implementation<charT> > m_pimpl;
676
+ //
677
+ // catalog name handler:
678
+ //
679
+ static std::string& get_catalog_name_inst();
680
+
681
+ #ifdef BOOST_HAS_THREADS
682
+ static static_mutex& get_mutex_inst();
683
+ #endif
684
+ };
685
+
686
+ template <class charT>
687
+ std::string w32_regex_traits<charT>::catalog_name(const std::string& name)
688
+ {
689
+ #ifdef BOOST_HAS_THREADS
690
+ static_mutex::scoped_lock lk(get_mutex_inst());
691
+ #endif
692
+ std::string result(get_catalog_name_inst());
693
+ get_catalog_name_inst() = name;
694
+ return result;
695
+ }
696
+
697
+ template <class charT>
698
+ std::string& w32_regex_traits<charT>::get_catalog_name_inst()
699
+ {
700
+ static std::string s_name;
701
+ return s_name;
702
+ }
703
+
704
+ template <class charT>
705
+ std::string w32_regex_traits<charT>::get_catalog_name()
706
+ {
707
+ #ifdef BOOST_HAS_THREADS
708
+ static_mutex::scoped_lock lk(get_mutex_inst());
709
+ #endif
710
+ std::string result(get_catalog_name_inst());
711
+ return result;
712
+ }
713
+
714
+ #ifdef BOOST_HAS_THREADS
715
+ template <class charT>
716
+ static_mutex& w32_regex_traits<charT>::get_mutex_inst()
717
+ {
718
+ static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
719
+ return s_mutex;
720
+ }
721
+ #endif
722
+
723
+
724
+ } // boost
725
+
726
+ #ifdef BOOST_MSVC
727
+ #pragma warning(pop)
728
+ #endif
729
+
730
+ #ifdef BOOST_MSVC
731
+ #pragma warning(push)
732
+ #pragma warning(disable: 4103)
733
+ #endif
734
+ #ifdef BOOST_HAS_ABI_HEADERS
735
+ # include BOOST_ABI_SUFFIX
736
+ #endif
737
+ #ifdef BOOST_MSVC
738
+ #pragma warning(pop)
739
+ #endif
740
+
741
+ #endif