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
22 #include <boost/regex.hpp>
23 #include <boost/cregex.hpp>
25 #if defined(BOOST_NO_STDC_NAMESPACE)
38 unsigned int magic_value
= 25631;
40 const char* names
[] = {
66 typedef boost::basic_regex
<char, c_regex_traits
<char> > c_regex_type
;
68 BOOST_REGEX_DECL
int BOOST_REGEX_CCALL
regcompA(regex_tA
* expression
, const char* ptr
, int f
)
70 if(expression
->re_magic
!= magic_value
)
73 #ifndef BOOST_NO_EXCEPTIONS
76 expression
->guts
= new c_regex_type();
77 #ifndef BOOST_NO_EXCEPTIONS
83 if(0 == expression
->guts
)
88 boost::uint_fast32_t flags
= (f
& REG_PERLEX
) ? 0 : ((f
& REG_EXTENDED
) ? regex::extended
: regex::basic
);
89 expression
->eflags
= (f
& REG_NEWLINE
) ? match_not_dot_newline
: match_default
;
90 // and translate those that are actually set:
94 flags
|= regex::nocollate
;
95 #ifndef BOOST_REGEX_V3
96 flags
&= ~regex::collate
;
102 //expression->eflags |= match_any;
103 flags
|= regex::nosubs
;
107 flags
|= regex::literal
;
109 flags
|= regex::icase
;
110 if(f
& REG_ESCAPE_IN_LISTS
)
111 flags
&= ~regex::no_escape_in_lists
;
112 if(f
& REG_NEWLINE_ALT
)
113 flags
|= regex::newline_alt
;
117 p2
= expression
->re_endp
;
118 else p2
= ptr
+ std::strlen(ptr
);
122 #ifndef BOOST_NO_EXCEPTIONS
125 expression
->re_magic
= magic_value
;
126 static_cast<c_regex_type
*>(expression
->guts
)->set_expression(ptr
, p2
, flags
);
127 expression
->re_nsub
= static_cast<c_regex_type
*>(expression
->guts
)->mark_count() - 1;
128 result
= static_cast<c_regex_type
*>(expression
->guts
)->error_code();
129 #ifndef BOOST_NO_EXCEPTIONS
131 catch(const boost::regex_error
& be
)
137 result
= REG_E_UNKNOWN
;
141 regfreeA(expression
);
146 BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL
regerrorA(int code
, const regex_tA
* e
, char* buf
, regsize_t buf_size
)
148 std::size_t result
= 0;
152 if(code
<= (int)REG_E_UNKNOWN
)
154 result
= std::strlen(names
[code
]) + 1;
155 if(buf_size
>= result
)
156 re_detail::strcpy_s(buf
, buf_size
, names
[code
]);
166 for(int i
= 0; i
<= (int)REG_E_UNKNOWN
; ++i
)
168 if(std::strcmp(e
->re_endp
, names
[i
]) == 0)
171 // We're converting an integer i to a string, and since i <= REG_E_UNKNOWN
172 // a five character string is *always* large enough:
174 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
175 int r
= (::sprintf_s
)(localbuf
, 5, "%d", i
);
177 int r
= (std::sprintf
)(localbuf
, "%d", i
);
180 return 0; // sprintf failed
181 if(std::strlen(localbuf
) < buf_size
)
182 re_detail::strcpy_s(buf
, buf_size
, localbuf
);
183 return std::strlen(localbuf
) + 1;
186 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
187 (::sprintf_s
)(localbuf
, 5, "%d", 0);
189 (std::sprintf
)(localbuf
, "%d", 0);
191 if(std::strlen(localbuf
) < buf_size
)
192 re_detail::strcpy_s(buf
, buf_size
, localbuf
);
193 return std::strlen(localbuf
) + 1;
195 if(code
<= (int)REG_E_UNKNOWN
)
198 if((e
) && (e
->re_magic
== magic_value
))
199 p
= static_cast<c_regex_type
*>(e
->guts
)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type
>(code
));
202 p
= re_detail::get_default_error_string(static_cast< ::boost::regex_constants::error_type
>(code
));
204 std::size_t len
= p
.size();
207 re_detail::strcpy_s(buf
, buf_size
, p
.c_str());
216 BOOST_REGEX_DECL
int BOOST_REGEX_CCALL
regexecA(const regex_tA
* expression
, const char* buf
, regsize_t n
, regmatch_t
* array
, int eflags
)
219 #pragma warning(push)
220 #pragma warning(disable:4267)
223 match_flag_type flags
= match_default
| expression
->eflags
;
228 if(eflags
& REG_NOTBOL
)
229 flags
|= match_not_bol
;
230 if(eflags
& REG_NOTEOL
)
231 flags
|= match_not_eol
;
232 if(eflags
& REG_STARTEND
)
234 start
= buf
+ array
[0].rm_so
;
235 end
= buf
+ array
[0].rm_eo
;
240 end
= buf
+ std::strlen(buf
);
243 #ifndef BOOST_NO_EXCEPTIONS
246 if(expression
->re_magic
== magic_value
)
248 result
= regex_search(start
, end
, m
, *static_cast<c_regex_type
*>(expression
->guts
), flags
);
252 #ifndef BOOST_NO_EXCEPTIONS
255 return REG_E_UNKNOWN
;
261 // extract what matched:
263 for(i
= 0; (i
< n
) && (i
< expression
->re_nsub
+ 1); ++i
)
265 array
[i
].rm_so
= (m
[i
].matched
== false) ? -1 : (m
[i
].first
- buf
);
266 array
[i
].rm_eo
= (m
[i
].matched
== false) ? -1 : (m
[i
].second
- buf
);
268 // and set anything else to -1:
269 for(i
= expression
->re_nsub
+ 1; i
< n
; ++i
)
282 BOOST_REGEX_DECL
void BOOST_REGEX_CCALL
regfreeA(regex_tA
* expression
)
284 if(expression
->re_magic
== magic_value
)
286 delete static_cast<c_regex_type
*>(expression
->guts
);
288 expression
->re_magic
= 0;