]> git.lyx.org Git - features.git/blob - 3rdparty/boost/libs/regex/src/c_regex_traits.cpp
Wininstaller2: refresh PATH before running configure
[features.git] / 3rdparty / boost / libs / regex / src / c_regex_traits.cpp
1 /*
2  *
3  * Copyright (c) 2004
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:        c_regex_traits.cpp
15   *   VERSION:     see <boost/version.hpp>
16   *   DESCRIPTION: Implements out of line c_regex_traits<char> members
17   */
18
19
20 #define BOOST_REGEX_SOURCE
21
22 #include <boost/config.hpp>
23 #include <boost/detail/workaround.hpp>
24 #include "internals.hpp"
25
26 #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560)
27
28 #include <boost/regex/v4/c_regex_traits.hpp>
29 #include <boost/regex/v4/primary_transform.hpp>
30 #include <boost/regex/v4/regex_traits_defaults.hpp>
31
32 #ifdef BOOST_NO_STDC_NAMESPACE
33 namespace std{
34    using ::strxfrm; using ::isspace;
35    using ::ispunct; using ::isalpha;
36    using ::isalnum; using ::iscntrl;
37    using ::isprint; using ::isupper;
38    using ::islower; using ::isdigit;
39    using ::isxdigit; using ::strtol;
40 }
41 #endif
42
43 #ifdef BOOST_HAS_ABI_HEADERS
44 #  include BOOST_ABI_PREFIX
45 #endif
46
47 namespace boost{
48
49 c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transform(const char* p1, const char* p2)
50
51    std::string result(10, ' ');
52    std::size_t s = result.size();
53    std::size_t r;
54    std::string src(p1, p2);
55    while(s < (r = std::strxfrm(&*result.begin(), src.c_str(), s)))
56    {
57 #if defined(_CPPLIB_VER)
58       //
59       // A bug in VC11 and 12 causes the program to hang if we pass a null-string
60       // to std::strxfrm, but only for certain locales :-(
61       // Probably effects Intel and Clang or any compiler using the VC std library (Dinkumware).
62       //
63       if(r == INT_MAX)
64       {
65          result.erase();
66          result.insert(result.begin(), static_cast<char>(0));
67          return result;
68       }
69 #endif
70       result.append(r - s + 3, ' ');
71       s = result.size();
72    }
73    result.erase(r);
74    return result; 
75 }
76
77 c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transform_primary(const char* p1, const char* p2)
78 {
79    static char s_delim;
80    static const int s_collate_type = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(static_cast<c_regex_traits<char>*>(0), &s_delim);
81    std::string result;
82    //
83    // What we do here depends upon the format of the sort key returned by
84    // sort key returned by this->transform:
85    //
86    switch(s_collate_type)
87    {
88    case ::boost::BOOST_REGEX_DETAIL_NS::sort_C:
89    case ::boost::BOOST_REGEX_DETAIL_NS::sort_unknown:
90       // the best we can do is translate to lower case, then get a regular sort key:
91       {
92          result.assign(p1, p2);
93          for(std::string::size_type i = 0; i < result.size(); ++i)
94             result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));
95          result = transform(&*result.begin(), &*result.begin() + result.size());
96          break;
97       }
98    case ::boost::BOOST_REGEX_DETAIL_NS::sort_fixed:
99       {
100          // get a regular sort key, and then truncate it:
101          result = transform(p1, p2);
102          result.erase(s_delim);
103          break;
104       }
105    case ::boost::BOOST_REGEX_DETAIL_NS::sort_delim:
106          // get a regular sort key, and then truncate everything after the delim:
107          result = transform(p1, p2);
108          if(result.size() && (result[0] == s_delim))
109             break;
110          std::size_t i;
111          for(i = 0; i < result.size(); ++i)
112          {
113             if(result[i] == s_delim)
114                break;
115          }
116          result.erase(i);
117          break;
118    }
119    if(result.empty())
120       result = std::string(1, char(0));
121    return result;
122 }
123
124 c_regex_traits<char>::char_class_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_classname(const char* p1, const char* p2)
125 {
126    static const char_class_type masks[] = 
127    {
128       0,
129       char_class_alnum, 
130       char_class_alpha,
131       char_class_blank,
132       char_class_cntrl,
133       char_class_digit,
134       char_class_digit,
135       char_class_graph,
136       char_class_horizontal,
137       char_class_lower,
138       char_class_lower,
139       char_class_print,
140       char_class_punct,
141       char_class_space,
142       char_class_space,
143       char_class_upper,
144       char_class_unicode,
145       char_class_upper,
146       char_class_vertical,
147       char_class_alnum | char_class_word, 
148       char_class_alnum | char_class_word, 
149       char_class_xdigit,
150    };
151
152    int idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(p1, p2);
153    if(idx < 0)
154    {
155       std::string s(p1, p2);
156       for(std::string::size_type i = 0; i < s.size(); ++i)
157          s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));
158       idx = ::boost::BOOST_REGEX_DETAIL_NS::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
159    }
160    BOOST_ASSERT(std::size_t(idx+1) < sizeof(masks) / sizeof(masks[0]));
161    return masks[idx+1];
162 }
163
164 bool BOOST_REGEX_CALL c_regex_traits<char>::isctype(char c, char_class_type mask)
165 {
166    return
167       ((mask & char_class_space) && (std::isspace)(static_cast<unsigned char>(c)))
168       || ((mask & char_class_print) && (std::isprint)(static_cast<unsigned char>(c)))
169       || ((mask & char_class_cntrl) && (std::iscntrl)(static_cast<unsigned char>(c)))
170       || ((mask & char_class_upper) && (std::isupper)(static_cast<unsigned char>(c)))
171       || ((mask & char_class_lower) && (std::islower)(static_cast<unsigned char>(c)))
172       || ((mask & char_class_alpha) && (std::isalpha)(static_cast<unsigned char>(c)))
173       || ((mask & char_class_digit) && (std::isdigit)(static_cast<unsigned char>(c)))
174       || ((mask & char_class_punct) && (std::ispunct)(static_cast<unsigned char>(c)))
175       || ((mask & char_class_xdigit) && (std::isxdigit)(static_cast<unsigned char>(c)))
176       || ((mask & char_class_blank) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c))
177       || ((mask & char_class_word) && (c == '_'))
178       || ((mask & char_class_vertical) && (::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) || (c == '\v')))
179       || ((mask & char_class_horizontal) && (std::isspace)(static_cast<unsigned char>(c)) && !::boost::BOOST_REGEX_DETAIL_NS::is_separator(c) && (c != '\v'));
180 }
181
182 c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::lookup_collatename(const char* p1, const char* p2)
183 {
184    std::string s(p1, p2);
185    s = ::boost::BOOST_REGEX_DETAIL_NS::lookup_default_collate_name(s);
186    if(s.empty() && (p2-p1 == 1))
187       s.append(1, *p1);
188    return s;
189 }
190
191 int BOOST_REGEX_CALL c_regex_traits<char>::value(char c, int radix)
192 {
193    char b[2] = { c, '\0', };
194    char* ep;
195    int result = std::strtol(b, &ep, radix);
196    if(ep == b)
197       return -1;
198    return result;
199 }
200
201 }
202 #ifdef BOOST_HAS_ABI_HEADERS
203 #  include BOOST_ABI_SUFFIX
204 #endif
205
206 #endif