3 * Copyright (c) 1998-2002
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)
13 * LOCATION: see http://www.boost.org for most recent version.
15 * VERSION: see <boost/version.hpp>
16 * DESCRIPTION: Implements the Posix API wrappers.
19 #define BOOST_REGEX_SOURCE
21 #include <boost/config.hpp>
23 #include <boost/regex.hpp>
24 #include <boost/cregex.hpp>
26 #if defined(BOOST_NO_STDC_NAMESPACE)
39 unsigned int magic_value
= 25631;
41 const char* names
[] = {
67 typedef boost::basic_regex
<char, c_regex_traits
<char> > c_regex_type
;
70 # pragma warning(push)
71 #pragma warning(disable:26812)
73 BOOST_REGEX_DECL
int BOOST_REGEX_CCALL
regcompA(regex_tA
* expression
, const char* ptr
, int f
)
75 #ifndef BOOST_NO_EXCEPTIONS
78 expression
->guts
= new c_regex_type();
79 #ifndef BOOST_NO_EXCEPTIONS
86 if(0 == expression
->guts
)
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:
96 flags
|= regex::nocollate
;
97 #ifndef BOOST_REGEX_V3
98 flags
&= ~regex::collate
;
104 //expression->eflags |= match_any;
105 flags
|= regex::nosubs
;
109 flags
|= regex::literal
;
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
;
119 p2
= expression
->re_endp
;
120 else p2
= ptr
+ std::strlen(ptr
);
124 #ifndef BOOST_NO_EXCEPTIONS
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
133 catch(const boost::regex_error
& be
)
139 result
= REG_E_UNKNOWN
;
143 regfreeA(expression
);
148 # pragma warning(pop)
151 BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL
regerrorA(int code
, const regex_tA
* e
, char* buf
, regsize_t buf_size
)
153 std::size_t result
= 0;
157 if(code
<= (int)REG_E_UNKNOWN
)
159 result
= std::strlen(names
[code
]) + 1;
160 if(buf_size
>= result
)
161 BOOST_REGEX_DETAIL_NS::strcpy_s(buf
, buf_size
, names
[code
]);
171 for(int i
= 0; i
<= (int)REG_E_UNKNOWN
; ++i
)
173 if(std::strcmp(e
->re_endp
, names
[i
]) == 0)
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:
179 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
180 int r
= (::sprintf_s
)(localbuf
, 5, "%d", i
);
182 int r
= (std::sprintf
)(localbuf
, "%d", i
);
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;
191 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
192 int r
= (::sprintf_s
)(localbuf
, 5, "%d", 0);
194 int r
= (std::sprintf
)(localbuf
, "%d", 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;
202 if(code
<= (int)REG_E_UNKNOWN
)
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
));
209 p
= BOOST_REGEX_DETAIL_NS::get_default_error_string(static_cast< ::boost::regex_constants::error_type
>(code
));
211 std::size_t len
= p
.size();
214 BOOST_REGEX_DETAIL_NS::strcpy_s(buf
, buf_size
, p
.c_str());
223 BOOST_REGEX_DECL
int BOOST_REGEX_CCALL
regexecA(const regex_tA
* expression
, const char* buf
, regsize_t n
, regmatch_t
* array
, int eflags
)
226 #pragma warning(push)
227 #pragma warning(disable:4267)
230 match_flag_type flags
= match_default
| expression
->eflags
;
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
)
241 start
= buf
+ array
[0].rm_so
;
242 end
= buf
+ array
[0].rm_eo
;
247 end
= buf
+ std::strlen(buf
);
250 #ifndef BOOST_NO_EXCEPTIONS
253 if(expression
->re_magic
== magic_value
)
255 result
= regex_search(start
, end
, m
, *static_cast<c_regex_type
*>(expression
->guts
), flags
);
259 #ifndef BOOST_NO_EXCEPTIONS
262 return REG_E_UNKNOWN
;
268 // extract what matched:
270 for(i
= 0; (i
< n
) && (i
< expression
->re_nsub
+ 1); ++i
)
272 array
[i
].rm_so
= (m
[i
].matched
== false) ? -1 : (m
[i
].first
- buf
);
273 array
[i
].rm_eo
= (m
[i
].matched
== false) ? -1 : (m
[i
].second
- buf
);
275 // and set anything else to -1:
276 for(i
= expression
->re_nsub
+ 1; i
< n
; ++i
)
289 BOOST_REGEX_DECL
void BOOST_REGEX_CCALL
regfreeA(regex_tA
* expression
)
291 if(expression
->re_magic
== magic_value
)
293 delete static_cast<c_regex_type
*>(expression
->guts
);
295 expression
->re_magic
= 0;