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