]> git.lyx.org Git - features.git/blob - 3rdparty/boost/libs/regex/src/posix_api.cpp
Update to boost 1.72
[features.git] / 3rdparty / boost / libs / regex / src / posix_api.cpp
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)
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
69 BOOST_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
144 BOOST_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
216 BOOST_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
282 BOOST_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