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,211 @@
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 c_regex_traits.hpp
15
+ * VERSION see <boost/version.hpp>
16
+ * DESCRIPTION: Declares regular expression traits class that wraps the global C locale.
17
+ */
18
+
19
+ #ifndef BOOST_C_REGEX_TRAITS_HPP_INCLUDED
20
+ #define BOOST_C_REGEX_TRAITS_HPP_INCLUDED
21
+
22
+ #ifndef BOOST_REGEX_CONFIG_HPP
23
+ #include <boost/regex/config.hpp>
24
+ #endif
25
+ #ifndef BOOST_REGEX_WORKAROUND_HPP
26
+ #include <boost/regex/v4/regex_workaround.hpp>
27
+ #endif
28
+
29
+ #include <cctype>
30
+
31
+ #ifdef BOOST_NO_STDC_NAMESPACE
32
+ namespace std{
33
+ using ::strlen; using ::tolower;
34
+ }
35
+ #endif
36
+
37
+ #ifdef BOOST_MSVC
38
+ #pragma warning(push)
39
+ #pragma warning(disable: 4103)
40
+ #endif
41
+ #ifdef BOOST_HAS_ABI_HEADERS
42
+ # include BOOST_ABI_PREFIX
43
+ #endif
44
+ #ifdef BOOST_MSVC
45
+ #pragma warning(pop)
46
+ #endif
47
+
48
+ namespace boost{
49
+
50
+ template <class charT>
51
+ struct c_regex_traits;
52
+
53
+ template<>
54
+ struct BOOST_REGEX_DECL c_regex_traits<char>
55
+ {
56
+ c_regex_traits(){}
57
+ typedef char char_type;
58
+ typedef std::size_t size_type;
59
+ typedef std::string string_type;
60
+ struct locale_type{};
61
+ typedef boost::uint32_t char_class_type;
62
+
63
+ static size_type length(const char_type* p)
64
+ {
65
+ return (std::strlen)(p);
66
+ }
67
+
68
+ char translate(char c) const
69
+ {
70
+ return c;
71
+ }
72
+ char translate_nocase(char c) const
73
+ {
74
+ return static_cast<char>((std::tolower)(static_cast<unsigned char>(c)));
75
+ }
76
+
77
+ static string_type BOOST_REGEX_CALL transform(const char* p1, const char* p2);
78
+ static string_type BOOST_REGEX_CALL transform_primary(const char* p1, const char* p2);
79
+
80
+ static char_class_type BOOST_REGEX_CALL lookup_classname(const char* p1, const char* p2);
81
+ static string_type BOOST_REGEX_CALL lookup_collatename(const char* p1, const char* p2);
82
+
83
+ static bool BOOST_REGEX_CALL isctype(char, char_class_type);
84
+ static int BOOST_REGEX_CALL value(char, int);
85
+
86
+ locale_type imbue(locale_type l)
87
+ { return l; }
88
+ locale_type getloc()const
89
+ { return locale_type(); }
90
+
91
+ private:
92
+ // this type is not copyable:
93
+ c_regex_traits(const c_regex_traits&);
94
+ c_regex_traits& operator=(const c_regex_traits&);
95
+ };
96
+
97
+ #ifndef BOOST_NO_WREGEX
98
+ template<>
99
+ struct BOOST_REGEX_DECL c_regex_traits<wchar_t>
100
+ {
101
+ c_regex_traits(){}
102
+ typedef wchar_t char_type;
103
+ typedef std::size_t size_type;
104
+ typedef std::wstring string_type;
105
+ struct locale_type{};
106
+ typedef boost::uint32_t char_class_type;
107
+
108
+ static size_type length(const char_type* p)
109
+ {
110
+ return (std::wcslen)(p);
111
+ }
112
+
113
+ wchar_t translate(wchar_t c) const
114
+ {
115
+ return c;
116
+ }
117
+ wchar_t translate_nocase(wchar_t c) const
118
+ {
119
+ return (std::towlower)(c);
120
+ }
121
+
122
+ static string_type BOOST_REGEX_CALL transform(const wchar_t* p1, const wchar_t* p2);
123
+ static string_type BOOST_REGEX_CALL transform_primary(const wchar_t* p1, const wchar_t* p2);
124
+
125
+ static char_class_type BOOST_REGEX_CALL lookup_classname(const wchar_t* p1, const wchar_t* p2);
126
+ static string_type BOOST_REGEX_CALL lookup_collatename(const wchar_t* p1, const wchar_t* p2);
127
+
128
+ static bool BOOST_REGEX_CALL isctype(wchar_t, char_class_type);
129
+ static int BOOST_REGEX_CALL value(wchar_t, int);
130
+
131
+ locale_type imbue(locale_type l)
132
+ { return l; }
133
+ locale_type getloc()const
134
+ { return locale_type(); }
135
+
136
+ private:
137
+ // this type is not copyable:
138
+ c_regex_traits(const c_regex_traits&);
139
+ c_regex_traits& operator=(const c_regex_traits&);
140
+ };
141
+
142
+ #ifdef BOOST_REGEX_HAS_OTHER_WCHAR_T
143
+ //
144
+ // Provide an unsigned short version as well, so the user can link to this
145
+ // no matter whether they build with /Zc:wchar_t or not (MSVC specific).
146
+ //
147
+ template<>
148
+ struct BOOST_REGEX_DECL c_regex_traits<unsigned short>
149
+ {
150
+ c_regex_traits(){}
151
+ typedef unsigned short char_type;
152
+ typedef std::size_t size_type;
153
+ typedef std::basic_string<unsigned short> string_type;
154
+ struct locale_type{};
155
+ typedef boost::uint32_t char_class_type;
156
+
157
+ static size_type length(const char_type* p)
158
+ {
159
+ return (std::wcslen)((const wchar_t*)p);
160
+ }
161
+
162
+ unsigned short translate(unsigned short c) const
163
+ {
164
+ return c;
165
+ }
166
+ unsigned short translate_nocase(unsigned short c) const
167
+ {
168
+ return (std::towlower)((wchar_t)c);
169
+ }
170
+
171
+ static string_type BOOST_REGEX_CALL transform(const unsigned short* p1, const unsigned short* p2);
172
+ static string_type BOOST_REGEX_CALL transform_primary(const unsigned short* p1, const unsigned short* p2);
173
+
174
+ static char_class_type BOOST_REGEX_CALL lookup_classname(const unsigned short* p1, const unsigned short* p2);
175
+ static string_type BOOST_REGEX_CALL lookup_collatename(const unsigned short* p1, const unsigned short* p2);
176
+
177
+ static bool BOOST_REGEX_CALL isctype(unsigned short, char_class_type);
178
+ static int BOOST_REGEX_CALL value(unsigned short, int);
179
+
180
+ locale_type imbue(locale_type l)
181
+ { return l; }
182
+ locale_type getloc()const
183
+ { return locale_type(); }
184
+
185
+ private:
186
+ // this type is not copyable:
187
+ c_regex_traits(const c_regex_traits&);
188
+ c_regex_traits& operator=(const c_regex_traits&);
189
+ };
190
+
191
+ #endif
192
+
193
+ #endif // BOOST_NO_WREGEX
194
+
195
+ }
196
+
197
+ #ifdef BOOST_MSVC
198
+ #pragma warning(push)
199
+ #pragma warning(disable: 4103)
200
+ #endif
201
+ #ifdef BOOST_HAS_ABI_HEADERS
202
+ # include BOOST_ABI_SUFFIX
203
+ #endif
204
+ #ifdef BOOST_MSVC
205
+ #pragma warning(pop)
206
+ #endif
207
+
208
+ #endif
209
+
210
+
211
+
@@ -0,0 +1,81 @@
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 char_regex_traits.cpp
15
+ * VERSION see <boost/version.hpp>
16
+ * DESCRIPTION: Declares deprecated traits classes char_regex_traits<>.
17
+ */
18
+
19
+
20
+ #ifndef BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
21
+ #define BOOST_REGEX_V4_CHAR_REGEX_TRAITS_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
+ namespace boost{
35
+
36
+ namespace deprecated{
37
+ //
38
+ // class char_regex_traits_i
39
+ // provides case insensitive traits classes (deprecated):
40
+ template <class charT>
41
+ class char_regex_traits_i : public regex_traits<charT> {};
42
+
43
+ template<>
44
+ class char_regex_traits_i<char> : public regex_traits<char>
45
+ {
46
+ public:
47
+ typedef char char_type;
48
+ typedef unsigned char uchar_type;
49
+ typedef unsigned int size_type;
50
+ typedef regex_traits<char> base_type;
51
+
52
+ };
53
+
54
+ #ifndef BOOST_NO_WREGEX
55
+ template<>
56
+ class char_regex_traits_i<wchar_t> : public regex_traits<wchar_t>
57
+ {
58
+ public:
59
+ typedef wchar_t char_type;
60
+ typedef unsigned short uchar_type;
61
+ typedef unsigned int size_type;
62
+ typedef regex_traits<wchar_t> base_type;
63
+
64
+ };
65
+ #endif
66
+ } // namespace deprecated
67
+ } // namespace boost
68
+
69
+ #ifdef BOOST_MSVC
70
+ #pragma warning(push)
71
+ #pragma warning(disable: 4103)
72
+ #endif
73
+ #ifdef BOOST_HAS_ABI_HEADERS
74
+ # include BOOST_ABI_SUFFIX
75
+ #endif
76
+ #ifdef BOOST_MSVC
77
+ #pragma warning(pop)
78
+ #endif
79
+
80
+ #endif // include
81
+
@@ -0,0 +1,1099 @@
1
+ /*
2
+ *
3
+ * Copyright (c) 2004 John Maddock
4
+ * Copyright 2011 Garmin Ltd. or its subsidiaries
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 cpp_regex_traits.hpp
15
+ * VERSION see <boost/version.hpp>
16
+ * DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
17
+ */
18
+
19
+ #ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
20
+ #define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
21
+
22
+ #include <boost/config.hpp>
23
+ #include <boost/integer.hpp>
24
+
25
+ #ifndef BOOST_NO_STD_LOCALE
26
+
27
+ #ifndef BOOST_RE_PAT_EXCEPT_HPP
28
+ #include <boost/regex/pattern_except.hpp>
29
+ #endif
30
+ #ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
31
+ #include <boost/regex/v4/regex_traits_defaults.hpp>
32
+ #endif
33
+ #ifdef BOOST_HAS_THREADS
34
+ #include <boost/regex/pending/static_mutex.hpp>
35
+ #endif
36
+ #ifndef BOOST_REGEX_PRIMARY_TRANSFORM
37
+ #include <boost/regex/v4/primary_transform.hpp>
38
+ #endif
39
+ #ifndef BOOST_REGEX_OBJECT_CACHE_HPP
40
+ #include <boost/regex/pending/object_cache.hpp>
41
+ #endif
42
+
43
+ #include <istream>
44
+ #include <ios>
45
+ #include <climits>
46
+
47
+ #ifdef BOOST_MSVC
48
+ #pragma warning(push)
49
+ #pragma warning(disable: 4103)
50
+ #endif
51
+ #ifdef BOOST_HAS_ABI_HEADERS
52
+ # include BOOST_ABI_PREFIX
53
+ #endif
54
+ #ifdef BOOST_MSVC
55
+ #pragma warning(pop)
56
+ #endif
57
+
58
+ #ifdef BOOST_MSVC
59
+ #pragma warning(push)
60
+ #pragma warning(disable:4786 4251)
61
+ #endif
62
+
63
+ namespace boost{
64
+
65
+ //
66
+ // forward declaration is needed by some compilers:
67
+ //
68
+ template <class charT>
69
+ class cpp_regex_traits;
70
+
71
+ namespace re_detail{
72
+
73
+ //
74
+ // class parser_buf:
75
+ // acts as a stream buffer which wraps around a pair of pointers:
76
+ //
77
+ template <class charT,
78
+ class traits = ::std::char_traits<charT> >
79
+ class parser_buf : public ::std::basic_streambuf<charT, traits>
80
+ {
81
+ typedef ::std::basic_streambuf<charT, traits> base_type;
82
+ typedef typename base_type::int_type int_type;
83
+ typedef typename base_type::char_type char_type;
84
+ typedef typename base_type::pos_type pos_type;
85
+ typedef ::std::streamsize streamsize;
86
+ typedef typename base_type::off_type off_type;
87
+ public:
88
+ parser_buf() : base_type() { setbuf(0, 0); }
89
+ const charT* getnext() { return this->gptr(); }
90
+ protected:
91
+ std::basic_streambuf<charT, traits>* setbuf(char_type* s, streamsize n);
92
+ typename parser_buf<charT, traits>::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which);
93
+ typename parser_buf<charT, traits>::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which);
94
+ private:
95
+ parser_buf& operator=(const parser_buf&);
96
+ parser_buf(const parser_buf&);
97
+ };
98
+
99
+ template<class charT, class traits>
100
+ std::basic_streambuf<charT, traits>*
101
+ parser_buf<charT, traits>::setbuf(char_type* s, streamsize n)
102
+ {
103
+ this->setg(s, s, s + n);
104
+ return this;
105
+ }
106
+
107
+ template<class charT, class traits>
108
+ typename parser_buf<charT, traits>::pos_type
109
+ parser_buf<charT, traits>::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which)
110
+ {
111
+ typedef typename boost::int_t<sizeof(way) * CHAR_BIT>::least cast_type;
112
+
113
+ if(which & ::std::ios_base::out)
114
+ return pos_type(off_type(-1));
115
+ std::ptrdiff_t size = this->egptr() - this->eback();
116
+ std::ptrdiff_t pos = this->gptr() - this->eback();
117
+ charT* g = this->eback();
118
+ switch(static_cast<cast_type>(way))
119
+ {
120
+ case ::std::ios_base::beg:
121
+ if((off < 0) || (off > size))
122
+ return pos_type(off_type(-1));
123
+ else
124
+ this->setg(g, g + off, g + size);
125
+ break;
126
+ case ::std::ios_base::end:
127
+ if((off < 0) || (off > size))
128
+ return pos_type(off_type(-1));
129
+ else
130
+ this->setg(g, g + size - off, g + size);
131
+ break;
132
+ case ::std::ios_base::cur:
133
+ {
134
+ std::ptrdiff_t newpos = static_cast<std::ptrdiff_t>(pos + off);
135
+ if((newpos < 0) || (newpos > size))
136
+ return pos_type(off_type(-1));
137
+ else
138
+ this->setg(g, g + newpos, g + size);
139
+ break;
140
+ }
141
+ default: ;
142
+ }
143
+ #ifdef BOOST_MSVC
144
+ #pragma warning(push)
145
+ #pragma warning(disable:4244)
146
+ #endif
147
+ return static_cast<pos_type>(this->gptr() - this->eback());
148
+ #ifdef BOOST_MSVC
149
+ #pragma warning(pop)
150
+ #endif
151
+ }
152
+
153
+ template<class charT, class traits>
154
+ typename parser_buf<charT, traits>::pos_type
155
+ parser_buf<charT, traits>::seekpos(pos_type sp, ::std::ios_base::openmode which)
156
+ {
157
+ if(which & ::std::ios_base::out)
158
+ return pos_type(off_type(-1));
159
+ off_type size = static_cast<off_type>(this->egptr() - this->eback());
160
+ charT* g = this->eback();
161
+ if(off_type(sp) <= size)
162
+ {
163
+ this->setg(g, g + off_type(sp), g + size);
164
+ }
165
+ return pos_type(off_type(-1));
166
+ }
167
+
168
+ //
169
+ // class cpp_regex_traits_base:
170
+ // acts as a container for locale and the facets we are using.
171
+ //
172
+ template <class charT>
173
+ struct cpp_regex_traits_base
174
+ {
175
+ cpp_regex_traits_base(const std::locale& l)
176
+ { imbue(l); }
177
+ std::locale imbue(const std::locale& l);
178
+
179
+ std::locale m_locale;
180
+ std::ctype<charT> const* m_pctype;
181
+ #ifndef BOOST_NO_STD_MESSAGES
182
+ std::messages<charT> const* m_pmessages;
183
+ #endif
184
+ std::collate<charT> const* m_pcollate;
185
+
186
+ bool operator<(const cpp_regex_traits_base& b)const
187
+ {
188
+ if(m_pctype == b.m_pctype)
189
+ {
190
+ #ifndef BOOST_NO_STD_MESSAGES
191
+ if(m_pmessages == b.m_pmessages)
192
+ {
193
+ return m_pcollate < b.m_pcollate;
194
+ }
195
+ return m_pmessages < b.m_pmessages;
196
+ #else
197
+ return m_pcollate < b.m_pcollate;
198
+ #endif
199
+ }
200
+ return m_pctype < b.m_pctype;
201
+ }
202
+ bool operator==(const cpp_regex_traits_base& b)const
203
+ {
204
+ return (m_pctype == b.m_pctype)
205
+ #ifndef BOOST_NO_STD_MESSAGES
206
+ && (m_pmessages == b.m_pmessages)
207
+ #endif
208
+ && (m_pcollate == b.m_pcollate);
209
+ }
210
+ };
211
+
212
+ template <class charT>
213
+ std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
214
+ {
215
+ std::locale result(m_locale);
216
+ m_locale = l;
217
+ m_pctype = &BOOST_USE_FACET(std::ctype<charT>, l);
218
+ #ifndef BOOST_NO_STD_MESSAGES
219
+ m_pmessages = BOOST_HAS_FACET(std::messages<charT>, l) ? &BOOST_USE_FACET(std::messages<charT>, l) : 0;
220
+ #endif
221
+ m_pcollate = &BOOST_USE_FACET(std::collate<charT>, l);
222
+ return result;
223
+ }
224
+
225
+ //
226
+ // class cpp_regex_traits_char_layer:
227
+ // implements methods that require specialisation for narrow characters:
228
+ //
229
+ template <class charT>
230
+ class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
231
+ {
232
+ typedef std::basic_string<charT> string_type;
233
+ typedef std::map<charT, regex_constants::syntax_type> map_type;
234
+ typedef typename map_type::const_iterator map_iterator_type;
235
+ public:
236
+ cpp_regex_traits_char_layer(const std::locale& l)
237
+ : cpp_regex_traits_base<charT>(l)
238
+ {
239
+ init();
240
+ }
241
+ cpp_regex_traits_char_layer(const cpp_regex_traits_base<charT>& b)
242
+ : cpp_regex_traits_base<charT>(b)
243
+ {
244
+ init();
245
+ }
246
+ void init();
247
+
248
+ regex_constants::syntax_type syntax_type(charT c)const
249
+ {
250
+ map_iterator_type i = m_char_map.find(c);
251
+ return ((i == m_char_map.end()) ? 0 : i->second);
252
+ }
253
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
254
+ {
255
+ map_iterator_type i = m_char_map.find(c);
256
+ if(i == m_char_map.end())
257
+ {
258
+ if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
259
+ if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
260
+ return 0;
261
+ }
262
+ return i->second;
263
+ }
264
+
265
+ private:
266
+ string_type get_default_message(regex_constants::syntax_type);
267
+ // TODO: use a hash table when available!
268
+ map_type m_char_map;
269
+ };
270
+
271
+ template <class charT>
272
+ void cpp_regex_traits_char_layer<charT>::init()
273
+ {
274
+ // we need to start by initialising our syntax map so we know which
275
+ // character is used for which purpose:
276
+ #ifndef BOOST_NO_STD_MESSAGES
277
+ #ifndef __IBMCPP__
278
+ typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
279
+ #else
280
+ typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
281
+ #endif
282
+ std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
283
+ if(cat_name.size() && (this->m_pmessages != 0))
284
+ {
285
+ cat = this->m_pmessages->open(
286
+ cat_name,
287
+ this->m_locale);
288
+ if((int)cat < 0)
289
+ {
290
+ std::string m("Unable to open message catalog: ");
291
+ std::runtime_error err(m + cat_name);
292
+ boost::re_detail::raise_runtime_error(err);
293
+ }
294
+ }
295
+ //
296
+ // if we have a valid catalog then load our messages:
297
+ //
298
+ if((int)cat >= 0)
299
+ {
300
+ #ifndef BOOST_NO_EXCEPTIONS
301
+ try{
302
+ #endif
303
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
304
+ {
305
+ string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
306
+ for(typename string_type::size_type j = 0; j < mss.size(); ++j)
307
+ {
308
+ m_char_map[mss[j]] = i;
309
+ }
310
+ }
311
+ this->m_pmessages->close(cat);
312
+ #ifndef BOOST_NO_EXCEPTIONS
313
+ }
314
+ catch(...)
315
+ {
316
+ if(this->m_pmessages)
317
+ this->m_pmessages->close(cat);
318
+ throw;
319
+ }
320
+ #endif
321
+ }
322
+ else
323
+ {
324
+ #endif
325
+ for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
326
+ {
327
+ const char* ptr = get_default_syntax(i);
328
+ while(ptr && *ptr)
329
+ {
330
+ m_char_map[this->m_pctype->widen(*ptr)] = i;
331
+ ++ptr;
332
+ }
333
+ }
334
+ #ifndef BOOST_NO_STD_MESSAGES
335
+ }
336
+ #endif
337
+ }
338
+
339
+ template <class charT>
340
+ typename cpp_regex_traits_char_layer<charT>::string_type
341
+ cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
342
+ {
343
+ const char* ptr = get_default_syntax(i);
344
+ string_type result;
345
+ while(ptr && *ptr)
346
+ {
347
+ result.append(1, this->m_pctype->widen(*ptr));
348
+ ++ptr;
349
+ }
350
+ return result;
351
+ }
352
+
353
+ //
354
+ // specialised version for narrow characters:
355
+ //
356
+ template <>
357
+ class BOOST_REGEX_DECL cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
358
+ {
359
+ typedef std::string string_type;
360
+ public:
361
+ cpp_regex_traits_char_layer(const std::locale& l)
362
+ : cpp_regex_traits_base<char>(l)
363
+ {
364
+ init();
365
+ }
366
+ cpp_regex_traits_char_layer(const cpp_regex_traits_base<char>& l)
367
+ : cpp_regex_traits_base<char>(l)
368
+ {
369
+ init();
370
+ }
371
+
372
+ regex_constants::syntax_type syntax_type(char c)const
373
+ {
374
+ return m_char_map[static_cast<unsigned char>(c)];
375
+ }
376
+ regex_constants::escape_syntax_type escape_syntax_type(char c) const
377
+ {
378
+ return m_char_map[static_cast<unsigned char>(c)];
379
+ }
380
+
381
+ private:
382
+ regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
383
+ void init();
384
+ };
385
+
386
+ #ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
387
+ enum
388
+ {
389
+ char_class_space=1<<0,
390
+ char_class_print=1<<1,
391
+ char_class_cntrl=1<<2,
392
+ char_class_upper=1<<3,
393
+ char_class_lower=1<<4,
394
+ char_class_alpha=1<<5,
395
+ char_class_digit=1<<6,
396
+ char_class_punct=1<<7,
397
+ char_class_xdigit=1<<8,
398
+ char_class_alnum=char_class_alpha|char_class_digit,
399
+ char_class_graph=char_class_alnum|char_class_punct,
400
+ char_class_blank=1<<9,
401
+ char_class_word=1<<10,
402
+ char_class_unicode=1<<11,
403
+ char_class_horizontal_space=1<<12,
404
+ char_class_vertical_space=1<<13
405
+ };
406
+
407
+ #endif
408
+
409
+ //
410
+ // class cpp_regex_traits_implementation:
411
+ // provides pimpl implementation for cpp_regex_traits.
412
+ //
413
+ template <class charT>
414
+ class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
415
+ {
416
+ public:
417
+ typedef typename cpp_regex_traits<charT>::char_class_type char_class_type;
418
+ typedef typename std::ctype<charT>::mask native_mask_type;
419
+ #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
420
+ BOOST_STATIC_CONSTANT(char_class_type, mask_blank = 1u << 24);
421
+ BOOST_STATIC_CONSTANT(char_class_type, mask_word = 1u << 25);
422
+ BOOST_STATIC_CONSTANT(char_class_type, mask_unicode = 1u << 26);
423
+ BOOST_STATIC_CONSTANT(char_class_type, mask_horizontal = 1u << 27);
424
+ BOOST_STATIC_CONSTANT(char_class_type, mask_vertical = 1u << 28);
425
+ #endif
426
+
427
+ typedef std::basic_string<charT> string_type;
428
+ typedef charT char_type;
429
+ //cpp_regex_traits_implementation();
430
+ cpp_regex_traits_implementation(const std::locale& l)
431
+ : cpp_regex_traits_char_layer<charT>(l)
432
+ {
433
+ init();
434
+ }
435
+ cpp_regex_traits_implementation(const cpp_regex_traits_base<charT>& l)
436
+ : cpp_regex_traits_char_layer<charT>(l)
437
+ {
438
+ init();
439
+ }
440
+ std::string error_string(regex_constants::error_type n) const
441
+ {
442
+ if(!m_error_strings.empty())
443
+ {
444
+ std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
445
+ return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
446
+ }
447
+ return get_default_error_string(n);
448
+ }
449
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
450
+ {
451
+ char_class_type result = lookup_classname_imp(p1, p2);
452
+ if(result == 0)
453
+ {
454
+ string_type temp(p1, p2);
455
+ this->m_pctype->tolower(&*temp.begin(), &*temp.begin() + temp.size());
456
+ result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
457
+ }
458
+ return result;
459
+ }
460
+ string_type lookup_collatename(const charT* p1, const charT* p2) const;
461
+ string_type transform_primary(const charT* p1, const charT* p2) const;
462
+ string_type transform(const charT* p1, const charT* p2) const;
463
+ private:
464
+ std::map<int, std::string> m_error_strings; // error messages indexed by numberic ID
465
+ std::map<string_type, char_class_type> m_custom_class_names; // character class names
466
+ std::map<string_type, string_type> m_custom_collate_names; // collating element names
467
+ unsigned m_collate_type; // the form of the collation string
468
+ charT m_collate_delim; // the collation group delimiter
469
+ //
470
+ // helpers:
471
+ //
472
+ char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
473
+ void init();
474
+ #ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
475
+ public:
476
+ bool isctype(charT c, char_class_type m)const;
477
+ #endif
478
+ };
479
+
480
+ #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
481
+ #if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
482
+
483
+ template <class charT>
484
+ typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
485
+ template <class charT>
486
+ typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
487
+ template <class charT>
488
+ typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
489
+ template <class charT>
490
+ typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_vertical;
491
+ template <class charT>
492
+ typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_horizontal;
493
+
494
+ #endif
495
+ #endif
496
+
497
+ template <class charT>
498
+ typename cpp_regex_traits_implementation<charT>::string_type
499
+ cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
500
+ {
501
+ //
502
+ // PRECONDITIONS:
503
+ //
504
+ // A bug in gcc 3.2 (and maybe other versions as well) treats
505
+ // p1 as a null terminated string, for efficiency reasons
506
+ // we work around this elsewhere, but just assert here that
507
+ // we adhere to gcc's (buggy) preconditions...
508
+ //
509
+ BOOST_ASSERT(*p2 == 0);
510
+
511
+ string_type result;
512
+ //
513
+ // swallowing all exceptions here is a bad idea
514
+ // however at least one std lib will always throw
515
+ // std::bad_alloc for certain arguments...
516
+ //
517
+ #ifndef BOOST_NO_EXCEPTIONS
518
+ try{
519
+ #endif
520
+ //
521
+ // What we do here depends upon the format of the sort key returned by
522
+ // sort key returned by this->transform:
523
+ //
524
+ switch(m_collate_type)
525
+ {
526
+ case sort_C:
527
+ case sort_unknown:
528
+ // the best we can do is translate to lower case, then get a regular sort key:
529
+ {
530
+ result.assign(p1, p2);
531
+ this->m_pctype->tolower(&*result.begin(), &*result.begin() + result.size());
532
+ result = this->m_pcollate->transform(&*result.begin(), &*result.begin() + result.size());
533
+ break;
534
+ }
535
+ case sort_fixed:
536
+ {
537
+ // get a regular sort key, and then truncate it:
538
+ result.assign(this->m_pcollate->transform(p1, p2));
539
+ result.erase(this->m_collate_delim);
540
+ break;
541
+ }
542
+ case sort_delim:
543
+ // get a regular sort key, and then truncate everything after the delim:
544
+ result.assign(this->m_pcollate->transform(p1, p2));
545
+ std::size_t i;
546
+ for(i = 0; i < result.size(); ++i)
547
+ {
548
+ if(result[i] == m_collate_delim)
549
+ break;
550
+ }
551
+ result.erase(i);
552
+ break;
553
+ }
554
+ #ifndef BOOST_NO_EXCEPTIONS
555
+ }catch(...){}
556
+ #endif
557
+ while(result.size() && (charT(0) == *result.rbegin()))
558
+ result.erase(result.size() - 1);
559
+ if(result.empty())
560
+ {
561
+ // character is ignorable at the primary level:
562
+ result = string_type(1, charT(0));
563
+ }
564
+ return result;
565
+ }
566
+
567
+ template <class charT>
568
+ typename cpp_regex_traits_implementation<charT>::string_type
569
+ cpp_regex_traits_implementation<charT>::transform(const charT* p1, const charT* p2) const
570
+ {
571
+ //
572
+ // PRECONDITIONS:
573
+ //
574
+ // A bug in gcc 3.2 (and maybe other versions as well) treats
575
+ // p1 as a null terminated string, for efficiency reasons
576
+ // we work around this elsewhere, but just assert here that
577
+ // we adhere to gcc's (buggy) preconditions...
578
+ //
579
+ BOOST_ASSERT(*p2 == 0);
580
+ //
581
+ // swallowing all exceptions here is a bad idea
582
+ // however at least one std lib will always throw
583
+ // std::bad_alloc for certain arguments...
584
+ //
585
+ string_type result;
586
+ #ifndef BOOST_NO_EXCEPTIONS
587
+ try{
588
+ #endif
589
+ result = this->m_pcollate->transform(p1, p2);
590
+ //
591
+ // Borland's STLPort version returns a NULL-terminated
592
+ // string that has garbage at the end - each call to
593
+ // std::collate<wchar_t>::transform returns a different string!
594
+ // So as a workaround, we'll truncate the string at the first NULL
595
+ // which _seems_ to work....
596
+ #if BOOST_WORKAROUND(__BORLANDC__, < 0x580)
597
+ result.erase(result.find(charT(0)));
598
+ #else
599
+ //
600
+ // some implementations (Dinkumware) append unnecessary trailing \0's:
601
+ while(result.size() && (charT(0) == *result.rbegin()))
602
+ result.erase(result.size() - 1);
603
+ #endif
604
+ BOOST_ASSERT(std::find(result.begin(), result.end(), charT(0)) == result.end());
605
+ #ifndef BOOST_NO_EXCEPTIONS
606
+ }
607
+ catch(...)
608
+ {
609
+ }
610
+ #endif
611
+ return result;
612
+ }
613
+
614
+
615
+ template <class charT>
616
+ typename cpp_regex_traits_implementation<charT>::string_type
617
+ cpp_regex_traits_implementation<charT>::lookup_collatename(const charT* p1, const charT* p2) const
618
+ {
619
+ typedef typename std::map<string_type, string_type>::const_iterator iter_type;
620
+ if(m_custom_collate_names.size())
621
+ {
622
+ iter_type pos = m_custom_collate_names.find(string_type(p1, p2));
623
+ if(pos != m_custom_collate_names.end())
624
+ return pos->second;
625
+ }
626
+ #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
627
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
628
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
629
+ std::string name(p1, p2);
630
+ #else
631
+ std::string name;
632
+ const charT* p0 = p1;
633
+ while(p0 != p2)
634
+ name.append(1, char(*p0++));
635
+ #endif
636
+ name = lookup_default_collate_name(name);
637
+ #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS)\
638
+ && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)\
639
+ && !BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
640
+ if(name.size())
641
+ return string_type(name.begin(), name.end());
642
+ #else
643
+ if(name.size())
644
+ {
645
+ string_type result;
646
+ typedef std::string::const_iterator iter;
647
+ iter b = name.begin();
648
+ iter e = name.end();
649
+ while(b != e)
650
+ result.append(1, charT(*b++));
651
+ return result;
652
+ }
653
+ #endif
654
+ if(p2 - p1 == 1)
655
+ return string_type(1, *p1);
656
+ return string_type();
657
+ }
658
+
659
+ template <class charT>
660
+ void cpp_regex_traits_implementation<charT>::init()
661
+ {
662
+ #ifndef BOOST_NO_STD_MESSAGES
663
+ #ifndef __IBMCPP__
664
+ typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
665
+ #else
666
+ typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
667
+ #endif
668
+ std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
669
+ if(cat_name.size() && (this->m_pmessages != 0))
670
+ {
671
+ cat = this->m_pmessages->open(
672
+ cat_name,
673
+ this->m_locale);
674
+ if((int)cat < 0)
675
+ {
676
+ std::string m("Unable to open message catalog: ");
677
+ std::runtime_error err(m + cat_name);
678
+ boost::re_detail::raise_runtime_error(err);
679
+ }
680
+ }
681
+ //
682
+ // if we have a valid catalog then load our messages:
683
+ //
684
+ if((int)cat >= 0)
685
+ {
686
+ //
687
+ // Error messages:
688
+ //
689
+ for(boost::regex_constants::error_type i = static_cast<boost::regex_constants::error_type>(0);
690
+ i <= boost::regex_constants::error_unknown;
691
+ i = static_cast<boost::regex_constants::error_type>(i + 1))
692
+ {
693
+ const char* p = get_default_error_string(i);
694
+ string_type default_message;
695
+ while(*p)
696
+ {
697
+ default_message.append(1, this->m_pctype->widen(*p));
698
+ ++p;
699
+ }
700
+ string_type s = this->m_pmessages->get(cat, 0, i+200, default_message);
701
+ std::string result;
702
+ for(std::string::size_type j = 0; j < s.size(); ++j)
703
+ {
704
+ result.append(1, this->m_pctype->narrow(s[j], 0));
705
+ }
706
+ m_error_strings[i] = result;
707
+ }
708
+ //
709
+ // Custom class names:
710
+ //
711
+ #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
712
+ static const char_class_type masks[16] =
713
+ {
714
+ std::ctype<charT>::alnum,
715
+ std::ctype<charT>::alpha,
716
+ std::ctype<charT>::cntrl,
717
+ std::ctype<charT>::digit,
718
+ std::ctype<charT>::graph,
719
+ cpp_regex_traits_implementation<charT>::mask_horizontal,
720
+ std::ctype<charT>::lower,
721
+ std::ctype<charT>::print,
722
+ std::ctype<charT>::punct,
723
+ std::ctype<charT>::space,
724
+ std::ctype<charT>::upper,
725
+ cpp_regex_traits_implementation<charT>::mask_vertical,
726
+ std::ctype<charT>::xdigit,
727
+ cpp_regex_traits_implementation<charT>::mask_blank,
728
+ cpp_regex_traits_implementation<charT>::mask_word,
729
+ cpp_regex_traits_implementation<charT>::mask_unicode,
730
+ };
731
+ #else
732
+ static const char_class_type masks[16] =
733
+ {
734
+ ::boost::re_detail::char_class_alnum,
735
+ ::boost::re_detail::char_class_alpha,
736
+ ::boost::re_detail::char_class_cntrl,
737
+ ::boost::re_detail::char_class_digit,
738
+ ::boost::re_detail::char_class_graph,
739
+ ::boost::re_detail::char_class_horizontal_space,
740
+ ::boost::re_detail::char_class_lower,
741
+ ::boost::re_detail::char_class_print,
742
+ ::boost::re_detail::char_class_punct,
743
+ ::boost::re_detail::char_class_space,
744
+ ::boost::re_detail::char_class_upper,
745
+ ::boost::re_detail::char_class_vertical_space,
746
+ ::boost::re_detail::char_class_xdigit,
747
+ ::boost::re_detail::char_class_blank,
748
+ ::boost::re_detail::char_class_word,
749
+ ::boost::re_detail::char_class_unicode,
750
+ };
751
+ #endif
752
+ static const string_type null_string;
753
+ for(unsigned int j = 0; j <= 13; ++j)
754
+ {
755
+ string_type s(this->m_pmessages->get(cat, 0, j+300, null_string));
756
+ if(s.size())
757
+ this->m_custom_class_names[s] = masks[j];
758
+ }
759
+ }
760
+ #endif
761
+ //
762
+ // get the collation format used by m_pcollate:
763
+ //
764
+ m_collate_type = re_detail::find_sort_syntax(this, &m_collate_delim);
765
+ }
766
+
767
+ template <class charT>
768
+ typename cpp_regex_traits_implementation<charT>::char_class_type
769
+ cpp_regex_traits_implementation<charT>::lookup_classname_imp(const charT* p1, const charT* p2) const
770
+ {
771
+ #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
772
+ static const char_class_type masks[22] =
773
+ {
774
+ 0,
775
+ std::ctype<char>::alnum,
776
+ std::ctype<char>::alpha,
777
+ cpp_regex_traits_implementation<charT>::mask_blank,
778
+ std::ctype<char>::cntrl,
779
+ std::ctype<char>::digit,
780
+ std::ctype<char>::digit,
781
+ std::ctype<char>::graph,
782
+ cpp_regex_traits_implementation<charT>::mask_horizontal,
783
+ std::ctype<char>::lower,
784
+ std::ctype<char>::lower,
785
+ std::ctype<char>::print,
786
+ std::ctype<char>::punct,
787
+ std::ctype<char>::space,
788
+ std::ctype<char>::space,
789
+ std::ctype<char>::upper,
790
+ cpp_regex_traits_implementation<charT>::mask_unicode,
791
+ std::ctype<char>::upper,
792
+ cpp_regex_traits_implementation<charT>::mask_vertical,
793
+ std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word,
794
+ std::ctype<char>::alnum | cpp_regex_traits_implementation<charT>::mask_word,
795
+ std::ctype<char>::xdigit,
796
+ };
797
+ #else
798
+ static const char_class_type masks[22] =
799
+ {
800
+ 0,
801
+ ::boost::re_detail::char_class_alnum,
802
+ ::boost::re_detail::char_class_alpha,
803
+ ::boost::re_detail::char_class_blank,
804
+ ::boost::re_detail::char_class_cntrl,
805
+ ::boost::re_detail::char_class_digit,
806
+ ::boost::re_detail::char_class_digit,
807
+ ::boost::re_detail::char_class_graph,
808
+ ::boost::re_detail::char_class_horizontal_space,
809
+ ::boost::re_detail::char_class_lower,
810
+ ::boost::re_detail::char_class_lower,
811
+ ::boost::re_detail::char_class_print,
812
+ ::boost::re_detail::char_class_punct,
813
+ ::boost::re_detail::char_class_space,
814
+ ::boost::re_detail::char_class_space,
815
+ ::boost::re_detail::char_class_upper,
816
+ ::boost::re_detail::char_class_unicode,
817
+ ::boost::re_detail::char_class_upper,
818
+ ::boost::re_detail::char_class_vertical_space,
819
+ ::boost::re_detail::char_class_alnum | ::boost::re_detail::char_class_word,
820
+ ::boost::re_detail::char_class_alnum | ::boost::re_detail::char_class_word,
821
+ ::boost::re_detail::char_class_xdigit,
822
+ };
823
+ #endif
824
+ if(m_custom_class_names.size())
825
+ {
826
+ typedef typename std::map<std::basic_string<charT>, char_class_type>::const_iterator map_iter;
827
+ map_iter pos = m_custom_class_names.find(string_type(p1, p2));
828
+ if(pos != m_custom_class_names.end())
829
+ return pos->second;
830
+ }
831
+ std::size_t state_id = 1 + re_detail::get_default_class_id(p1, p2);
832
+ BOOST_ASSERT(state_id < sizeof(masks) / sizeof(masks[0]));
833
+ return masks[state_id];
834
+ }
835
+
836
+ #ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
837
+ template <class charT>
838
+ bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_type mask) const
839
+ {
840
+ return
841
+ ((mask & ::boost::re_detail::char_class_space) && (this->m_pctype->is(std::ctype<charT>::space, c)))
842
+ || ((mask & ::boost::re_detail::char_class_print) && (this->m_pctype->is(std::ctype<charT>::print, c)))
843
+ || ((mask & ::boost::re_detail::char_class_cntrl) && (this->m_pctype->is(std::ctype<charT>::cntrl, c)))
844
+ || ((mask & ::boost::re_detail::char_class_upper) && (this->m_pctype->is(std::ctype<charT>::upper, c)))
845
+ || ((mask & ::boost::re_detail::char_class_lower) && (this->m_pctype->is(std::ctype<charT>::lower, c)))
846
+ || ((mask & ::boost::re_detail::char_class_alpha) && (this->m_pctype->is(std::ctype<charT>::alpha, c)))
847
+ || ((mask & ::boost::re_detail::char_class_digit) && (this->m_pctype->is(std::ctype<charT>::digit, c)))
848
+ || ((mask & ::boost::re_detail::char_class_punct) && (this->m_pctype->is(std::ctype<charT>::punct, c)))
849
+ || ((mask & ::boost::re_detail::char_class_xdigit) && (this->m_pctype->is(std::ctype<charT>::xdigit, c)))
850
+ || ((mask & ::boost::re_detail::char_class_blank) && (this->m_pctype->is(std::ctype<charT>::space, c)) && !::boost::re_detail::is_separator(c))
851
+ || ((mask & ::boost::re_detail::char_class_word) && (c == '_'))
852
+ || ((mask & ::boost::re_detail::char_class_unicode) && ::boost::re_detail::is_extended(c))
853
+ || ((mask & ::boost::re_detail::char_class_vertical_space) && (is_separator(c) || (c == '\v')))
854
+ || ((mask & ::boost::re_detail::char_class_horizontal_space) && this->m_pctype->is(std::ctype<charT>::space, c) && !(is_separator(c) || (c == '\v')));
855
+ }
856
+ #endif
857
+
858
+
859
+ template <class charT>
860
+ inline boost::shared_ptr<const cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
861
+ {
862
+ cpp_regex_traits_base<charT> key(l);
863
+ return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);
864
+ }
865
+
866
+ } // re_detail
867
+
868
+ template <class charT>
869
+ class cpp_regex_traits
870
+ {
871
+ private:
872
+ typedef std::ctype<charT> ctype_type;
873
+ public:
874
+ typedef charT char_type;
875
+ typedef std::size_t size_type;
876
+ typedef std::basic_string<char_type> string_type;
877
+ typedef std::locale locale_type;
878
+ typedef boost::uint_least32_t char_class_type;
879
+
880
+ struct boost_extensions_tag{};
881
+
882
+ cpp_regex_traits()
883
+ : m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
884
+ { }
885
+ static size_type length(const char_type* p)
886
+ {
887
+ return std::char_traits<charT>::length(p);
888
+ }
889
+ regex_constants::syntax_type syntax_type(charT c)const
890
+ {
891
+ return m_pimpl->syntax_type(c);
892
+ }
893
+ regex_constants::escape_syntax_type escape_syntax_type(charT c) const
894
+ {
895
+ return m_pimpl->escape_syntax_type(c);
896
+ }
897
+ charT translate(charT c) const
898
+ {
899
+ return c;
900
+ }
901
+ charT translate_nocase(charT c) const
902
+ {
903
+ return m_pimpl->m_pctype->tolower(c);
904
+ }
905
+ charT translate(charT c, bool icase) const
906
+ {
907
+ return icase ? m_pimpl->m_pctype->tolower(c) : c;
908
+ }
909
+ charT tolower(charT c) const
910
+ {
911
+ return m_pimpl->m_pctype->tolower(c);
912
+ }
913
+ charT toupper(charT c) const
914
+ {
915
+ return m_pimpl->m_pctype->toupper(c);
916
+ }
917
+ string_type transform(const charT* p1, const charT* p2) const
918
+ {
919
+ return m_pimpl->transform(p1, p2);
920
+ }
921
+ string_type transform_primary(const charT* p1, const charT* p2) const
922
+ {
923
+ return m_pimpl->transform_primary(p1, p2);
924
+ }
925
+ char_class_type lookup_classname(const charT* p1, const charT* p2) const
926
+ {
927
+ return m_pimpl->lookup_classname(p1, p2);
928
+ }
929
+ string_type lookup_collatename(const charT* p1, const charT* p2) const
930
+ {
931
+ return m_pimpl->lookup_collatename(p1, p2);
932
+ }
933
+ bool isctype(charT c, char_class_type f) const
934
+ {
935
+ #ifndef BOOST_REGEX_BUGGY_CTYPE_FACET
936
+ typedef typename std::ctype<charT>::mask ctype_mask;
937
+
938
+ static const ctype_mask mask_base =
939
+ static_cast<ctype_mask>(
940
+ std::ctype<charT>::alnum
941
+ | std::ctype<charT>::alpha
942
+ | std::ctype<charT>::cntrl
943
+ | std::ctype<charT>::digit
944
+ | std::ctype<charT>::graph
945
+ | std::ctype<charT>::lower
946
+ | std::ctype<charT>::print
947
+ | std::ctype<charT>::punct
948
+ | std::ctype<charT>::space
949
+ | std::ctype<charT>::upper
950
+ | std::ctype<charT>::xdigit);
951
+
952
+ if((f & mask_base)
953
+ && (m_pimpl->m_pctype->is(
954
+ static_cast<ctype_mask>(f & mask_base), c)))
955
+ return true;
956
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
957
+ return true;
958
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_word) && (c == '_'))
959
+ return true;
960
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_blank)
961
+ && m_pimpl->m_pctype->is(std::ctype<charT>::space, c)
962
+ && !re_detail::is_separator(c))
963
+ return true;
964
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_vertical)
965
+ && (::boost::re_detail::is_separator(c) || (c == '\v')))
966
+ return true;
967
+ else if((f & re_detail::cpp_regex_traits_implementation<charT>::mask_horizontal)
968
+ && this->isctype(c, std::ctype<charT>::space) && !this->isctype(c, re_detail::cpp_regex_traits_implementation<charT>::mask_vertical))
969
+ return true;
970
+ return false;
971
+ #else
972
+ return m_pimpl->isctype(c, f);
973
+ #endif
974
+ }
975
+ int toi(const charT*& p1, const charT* p2, int radix)const;
976
+ int value(charT c, int radix)const
977
+ {
978
+ const charT* pc = &c;
979
+ return toi(pc, pc + 1, radix);
980
+ }
981
+ locale_type imbue(locale_type l)
982
+ {
983
+ std::locale result(getloc());
984
+ m_pimpl = re_detail::create_cpp_regex_traits<charT>(l);
985
+ return result;
986
+ }
987
+ locale_type getloc()const
988
+ {
989
+ return m_pimpl->m_locale;
990
+ }
991
+ std::string error_string(regex_constants::error_type n) const
992
+ {
993
+ return m_pimpl->error_string(n);
994
+ }
995
+
996
+ //
997
+ // extension:
998
+ // set the name of the message catalog in use (defaults to "boost_regex").
999
+ //
1000
+ static std::string catalog_name(const std::string& name);
1001
+ static std::string get_catalog_name();
1002
+
1003
+ private:
1004
+ boost::shared_ptr<const re_detail::cpp_regex_traits_implementation<charT> > m_pimpl;
1005
+ //
1006
+ // catalog name handler:
1007
+ //
1008
+ static std::string& get_catalog_name_inst();
1009
+
1010
+ #ifdef BOOST_HAS_THREADS
1011
+ static static_mutex& get_mutex_inst();
1012
+ #endif
1013
+ };
1014
+
1015
+
1016
+ template <class charT>
1017
+ int cpp_regex_traits<charT>::toi(const charT*& first, const charT* last, int radix)const
1018
+ {
1019
+ re_detail::parser_buf<charT> sbuf; // buffer for parsing numbers.
1020
+ std::basic_istream<charT> is(&sbuf); // stream for parsing numbers.
1021
+
1022
+ // we do NOT want to parse any thousands separators inside the stream:
1023
+ last = std::find(first, last, BOOST_USE_FACET(std::numpunct<charT>, is.getloc()).thousands_sep());
1024
+
1025
+ sbuf.pubsetbuf(const_cast<charT*>(static_cast<const charT*>(first)), static_cast<std::streamsize>(last-first));
1026
+ is.clear();
1027
+ if(std::abs(radix) == 16) is >> std::hex;
1028
+ else if(std::abs(radix) == 8) is >> std::oct;
1029
+ else is >> std::dec;
1030
+ int val;
1031
+ if(is >> val)
1032
+ {
1033
+ first = first + ((last - first) - sbuf.in_avail());
1034
+ return val;
1035
+ }
1036
+ else
1037
+ return -1;
1038
+ }
1039
+
1040
+ template <class charT>
1041
+ std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
1042
+ {
1043
+ #ifdef BOOST_HAS_THREADS
1044
+ static_mutex::scoped_lock lk(get_mutex_inst());
1045
+ #endif
1046
+ std::string result(get_catalog_name_inst());
1047
+ get_catalog_name_inst() = name;
1048
+ return result;
1049
+ }
1050
+
1051
+ template <class charT>
1052
+ std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
1053
+ {
1054
+ static std::string s_name;
1055
+ return s_name;
1056
+ }
1057
+
1058
+ template <class charT>
1059
+ std::string cpp_regex_traits<charT>::get_catalog_name()
1060
+ {
1061
+ #ifdef BOOST_HAS_THREADS
1062
+ static_mutex::scoped_lock lk(get_mutex_inst());
1063
+ #endif
1064
+ std::string result(get_catalog_name_inst());
1065
+ return result;
1066
+ }
1067
+
1068
+ #ifdef BOOST_HAS_THREADS
1069
+ template <class charT>
1070
+ static_mutex& cpp_regex_traits<charT>::get_mutex_inst()
1071
+ {
1072
+ static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
1073
+ return s_mutex;
1074
+ }
1075
+ #endif
1076
+
1077
+
1078
+ } // boost
1079
+
1080
+ #ifdef BOOST_MSVC
1081
+ #pragma warning(pop)
1082
+ #endif
1083
+
1084
+ #ifdef BOOST_MSVC
1085
+ #pragma warning(push)
1086
+ #pragma warning(disable: 4103)
1087
+ #endif
1088
+ #ifdef BOOST_HAS_ABI_HEADERS
1089
+ # include BOOST_ABI_SUFFIX
1090
+ #endif
1091
+ #ifdef BOOST_MSVC
1092
+ #pragma warning(pop)
1093
+ #endif
1094
+
1095
+ #endif
1096
+
1097
+ #endif
1098
+
1099
+