]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* |
2 | * | |
3 | * Copyright (c) 1998-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: posix_api.cpp | |
15 | * VERSION: see <boost/version.hpp> | |
16 | * DESCRIPTION: Implements the Posix API wrappers. | |
17 | */ | |
18 | ||
19 | #define BOOST_REGEX_SOURCE | |
20 | ||
21 | #include <boost/config.hpp> | |
7c673cae FG |
22 | #include <boost/regex.hpp> |
23 | #include <boost/cregex.hpp> | |
1e59de90 | 24 | #include <cstdio> |
7c673cae FG |
25 | |
26 | #if defined(BOOST_NO_STDC_NAMESPACE) | |
27 | namespace std{ | |
28 | using ::sprintf; | |
29 | using ::strcpy; | |
30 | using ::strcmp; | |
31 | } | |
32 | #endif | |
33 | ||
34 | ||
35 | namespace boost{ | |
36 | ||
37 | namespace{ | |
38 | ||
39 | unsigned int magic_value = 25631; | |
40 | ||
41 | const char* names[] = { | |
42 | "REG_NOERROR", | |
43 | "REG_NOMATCH", | |
44 | "REG_BADPAT", | |
45 | "REG_ECOLLATE", | |
46 | "REG_ECTYPE", | |
47 | "REG_EESCAPE", | |
48 | "REG_ESUBREG", | |
49 | "REG_EBRACK", | |
50 | "REG_EPAREN", | |
51 | "REG_EBRACE", | |
52 | "REG_BADBR", | |
53 | "REG_ERANGE", | |
54 | "REG_ESPACE", | |
55 | "REG_BADRPT", | |
56 | "REG_EEND", | |
57 | "REG_ESIZE", | |
58 | "REG_ERPAREN", | |
59 | "REG_EMPTY", | |
60 | "REG_ECOMPLEXITY", | |
61 | "REG_ESTACK", | |
62 | "REG_E_PERL", | |
63 | "REG_E_UNKNOWN", | |
64 | }; | |
65 | } // namespace | |
66 | ||
67 | typedef boost::basic_regex<char, c_regex_traits<char> > c_regex_type; | |
68 | ||
20effc67 TL |
69 | #ifdef BOOST_MSVC |
70 | # pragma warning(push) | |
71 | #pragma warning(disable:26812) | |
72 | #endif | |
7c673cae FG |
73 | BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char* ptr, int f) |
74 | { | |
75 | #ifndef BOOST_NO_EXCEPTIONS | |
76 | try{ | |
77 | #endif | |
78 | expression->guts = new c_regex_type(); | |
79 | #ifndef BOOST_NO_EXCEPTIONS | |
80 | } catch(...) | |
81 | { | |
82 | expression->guts = 0; | |
83 | return REG_ESPACE; | |
84 | } | |
85 | #else | |
86 | if(0 == expression->guts) | |
87 | return REG_E_MEMORY; | |
88 | #endif | |
89 | // set default flags: | |
90 | boost::uint_fast32_t flags = (f & REG_PERLEX) ? 0 : ((f & REG_EXTENDED) ? regex::extended : regex::basic); | |
91 | expression->eflags = (f & REG_NEWLINE) ? match_not_dot_newline : match_default; | |
92 | // and translate those that are actually set: | |
93 | ||
94 | if(f & REG_NOCOLLATE) | |
95 | { | |
96 | flags |= regex::nocollate; | |
97 | #ifndef BOOST_REGEX_V3 | |
98 | flags &= ~regex::collate; | |
99 | #endif | |
100 | } | |
101 | ||
102 | if(f & REG_NOSUB) | |
103 | { | |
104 | //expression->eflags |= match_any; | |
105 | flags |= regex::nosubs; | |
106 | } | |
107 | ||
108 | if(f & REG_NOSPEC) | |
109 | flags |= regex::literal; | |
110 | if(f & REG_ICASE) | |
111 | flags |= regex::icase; | |
112 | if(f & REG_ESCAPE_IN_LISTS) | |
113 | flags &= ~regex::no_escape_in_lists; | |
114 | if(f & REG_NEWLINE_ALT) | |
115 | flags |= regex::newline_alt; | |
116 | ||
117 | const char* p2; | |
118 | if(f & REG_PEND) | |
119 | p2 = expression->re_endp; | |
120 | else p2 = ptr + std::strlen(ptr); | |
121 | ||
122 | int result; | |
123 | ||
124 | #ifndef BOOST_NO_EXCEPTIONS | |
125 | try{ | |
126 | #endif | |
127 | expression->re_magic = magic_value; | |
128 | static_cast<c_regex_type*>(expression->guts)->set_expression(ptr, p2, flags); | |
129 | expression->re_nsub = static_cast<c_regex_type*>(expression->guts)->mark_count(); | |
130 | result = static_cast<c_regex_type*>(expression->guts)->error_code(); | |
131 | #ifndef BOOST_NO_EXCEPTIONS | |
132 | } | |
133 | catch(const boost::regex_error& be) | |
134 | { | |
135 | result = be.code(); | |
136 | } | |
137 | catch(...) | |
138 | { | |
139 | result = REG_E_UNKNOWN; | |
140 | } | |
141 | #endif | |
142 | if(result) | |
143 | regfreeA(expression); | |
144 | return result; | |
145 | ||
146 | } | |
20effc67 TL |
147 | #ifdef BOOST_MSVC |
148 | # pragma warning(pop) | |
149 | #endif | |
7c673cae FG |
150 | |
151 | BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA* e, char* buf, regsize_t buf_size) | |
152 | { | |
153 | std::size_t result = 0; | |
154 | if(code & REG_ITOA) | |
155 | { | |
156 | code &= ~REG_ITOA; | |
157 | if(code <= (int)REG_E_UNKNOWN) | |
158 | { | |
159 | result = std::strlen(names[code]) + 1; | |
160 | if(buf_size >= result) | |
161 | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, names[code]); | |
162 | return result; | |
163 | } | |
164 | return result; | |
165 | } | |
166 | if(code == REG_ATOI) | |
167 | { | |
168 | char localbuf[5]; | |
169 | if(e == 0) | |
170 | return 0; | |
171 | for(int i = 0; i <= (int)REG_E_UNKNOWN; ++i) | |
172 | { | |
173 | if(std::strcmp(e->re_endp, names[i]) == 0) | |
174 | { | |
175 | // | |
176 | // We're converting an integer i to a string, and since i <= REG_E_UNKNOWN | |
177 | // a five character string is *always* large enough: | |
178 | // | |
179 | #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) | |
180 | int r = (::sprintf_s)(localbuf, 5, "%d", i); | |
181 | #else | |
182 | int r = (std::sprintf)(localbuf, "%d", i); | |
183 | #endif | |
184 | if(r < 0) | |
185 | return 0; // sprintf failed | |
186 | if(std::strlen(localbuf) < buf_size) | |
187 | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, localbuf); | |
188 | return std::strlen(localbuf) + 1; | |
189 | } | |
190 | } | |
191 | #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) | |
192 | int r = (::sprintf_s)(localbuf, 5, "%d", 0); | |
193 | #else | |
194 | int r = (std::sprintf)(localbuf, "%d", 0); | |
195 | #endif | |
196 | if(r < 0) | |
197 | return 0; // sprintf failed | |
198 | if(std::strlen(localbuf) < buf_size) | |
199 | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, localbuf); | |
200 | return std::strlen(localbuf) + 1; | |
201 | } | |
202 | if(code <= (int)REG_E_UNKNOWN) | |
203 | { | |
204 | std::string p; | |
205 | if((e) && (e->re_magic == magic_value)) | |
206 | p = static_cast<c_regex_type*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code)); | |
207 | else | |
208 | { | |
209 | p = BOOST_REGEX_DETAIL_NS::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code)); | |
210 | } | |
211 | std::size_t len = p.size(); | |
212 | if(len < buf_size) | |
213 | { | |
214 | BOOST_REGEX_DETAIL_NS::strcpy_s(buf, buf_size, p.c_str()); | |
215 | } | |
216 | return len + 1; | |
217 | } | |
218 | if(buf_size) | |
219 | *buf = 0; | |
220 | return 0; | |
221 | } | |
222 | ||
223 | BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA* expression, const char* buf, regsize_t n, regmatch_t* array, int eflags) | |
224 | { | |
225 | #ifdef BOOST_MSVC | |
226 | #pragma warning(push) | |
227 | #pragma warning(disable:4267) | |
228 | #endif | |
229 | bool result = false; | |
230 | match_flag_type flags = match_default | expression->eflags; | |
231 | const char* end; | |
232 | const char* start; | |
233 | cmatch m; | |
234 | ||
235 | if(eflags & REG_NOTBOL) | |
236 | flags |= match_not_bol; | |
237 | if(eflags & REG_NOTEOL) | |
238 | flags |= match_not_eol; | |
239 | if(eflags & REG_STARTEND) | |
240 | { | |
241 | start = buf + array[0].rm_so; | |
242 | end = buf + array[0].rm_eo; | |
243 | } | |
244 | else | |
245 | { | |
246 | start = buf; | |
247 | end = buf + std::strlen(buf); | |
248 | } | |
249 | ||
250 | #ifndef BOOST_NO_EXCEPTIONS | |
251 | try{ | |
252 | #endif | |
253 | if(expression->re_magic == magic_value) | |
254 | { | |
255 | result = regex_search(start, end, m, *static_cast<c_regex_type*>(expression->guts), flags); | |
256 | } | |
257 | else | |
258 | return result; | |
259 | #ifndef BOOST_NO_EXCEPTIONS | |
260 | } catch(...) | |
261 | { | |
262 | return REG_E_UNKNOWN; | |
263 | } | |
264 | #endif | |
265 | ||
266 | if(result) | |
267 | { | |
268 | // extract what matched: | |
269 | std::size_t i; | |
270 | for(i = 0; (i < n) && (i < expression->re_nsub + 1); ++i) | |
271 | { | |
1e59de90 TL |
272 | array[i].rm_so = m[i].matched ? (m[i].first - buf) : -1; |
273 | array[i].rm_eo = m[i].matched ? (m[i].second - buf) : -1; | |
7c673cae FG |
274 | } |
275 | // and set anything else to -1: | |
276 | for(i = expression->re_nsub + 1; i < n; ++i) | |
277 | { | |
278 | array[i].rm_so = -1; | |
279 | array[i].rm_eo = -1; | |
280 | } | |
281 | return 0; | |
282 | } | |
283 | return REG_NOMATCH; | |
284 | #ifdef BOOST_MSVC | |
285 | #pragma warning(pop) | |
286 | #endif | |
287 | } | |
288 | ||
289 | BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA* expression) | |
290 | { | |
291 | if(expression->re_magic == magic_value) | |
292 | { | |
293 | delete static_cast<c_regex_type*>(expression->guts); | |
294 | } | |
295 | expression->re_magic = 0; | |
296 | } | |
297 | ||
298 | } // namespace boost |