xref: /freebsd-12.1/contrib/libc++/src/regex.cpp (revision 7c82a1ec)
17a984708SDavid Chisnall //===-------------------------- regex.cpp ---------------------------------===//
27a984708SDavid Chisnall //
37a984708SDavid Chisnall //                     The LLVM Compiler Infrastructure
47a984708SDavid Chisnall //
57a984708SDavid Chisnall // This file is dual licensed under the MIT and the University of Illinois Open
67a984708SDavid Chisnall // Source Licenses. See LICENSE.TXT for details.
77a984708SDavid Chisnall //
87a984708SDavid Chisnall //===----------------------------------------------------------------------===//
97a984708SDavid Chisnall 
107a984708SDavid Chisnall #include "regex"
117a984708SDavid Chisnall #include "algorithm"
127a984708SDavid Chisnall #include "iterator"
137a984708SDavid Chisnall 
147a984708SDavid Chisnall _LIBCPP_BEGIN_NAMESPACE_STD
157a984708SDavid Chisnall 
167a984708SDavid Chisnall static
177a984708SDavid Chisnall const char*
make_error_type_string(regex_constants::error_type ecode)187a984708SDavid Chisnall make_error_type_string(regex_constants::error_type ecode)
197a984708SDavid Chisnall {
207a984708SDavid Chisnall     switch (ecode)
217a984708SDavid Chisnall     {
227a984708SDavid Chisnall     case regex_constants::error_collate:
237a984708SDavid Chisnall         return "The expression contained an invalid collating element name.";
247a984708SDavid Chisnall     case regex_constants::error_ctype:
257a984708SDavid Chisnall         return "The expression contained an invalid character class name.";
267a984708SDavid Chisnall     case regex_constants::error_escape:
277a984708SDavid Chisnall         return "The expression contained an invalid escaped character, or a "
287a984708SDavid Chisnall                "trailing escape.";
297a984708SDavid Chisnall     case regex_constants::error_backref:
307a984708SDavid Chisnall         return "The expression contained an invalid back reference.";
317a984708SDavid Chisnall     case regex_constants::error_brack:
327a984708SDavid Chisnall         return "The expression contained mismatched [ and ].";
337a984708SDavid Chisnall     case regex_constants::error_paren:
347a984708SDavid Chisnall         return "The expression contained mismatched ( and ).";
357a984708SDavid Chisnall     case regex_constants::error_brace:
367a984708SDavid Chisnall         return "The expression contained mismatched { and }.";
377a984708SDavid Chisnall     case regex_constants::error_badbrace:
387a984708SDavid Chisnall         return "The expression contained an invalid range in a {} expression.";
397a984708SDavid Chisnall     case regex_constants::error_range:
407a984708SDavid Chisnall         return "The expression contained an invalid character range, "
417a984708SDavid Chisnall                "such as [b-a] in most encodings.";
427a984708SDavid Chisnall     case regex_constants::error_space:
437a984708SDavid Chisnall         return "There was insufficient memory to convert the expression into "
447a984708SDavid Chisnall                "a finite state machine.";
457a984708SDavid Chisnall     case regex_constants::error_badrepeat:
467a984708SDavid Chisnall         return "One of *?+{ was not preceded by a valid regular expression.";
477a984708SDavid Chisnall     case regex_constants::error_complexity:
487a984708SDavid Chisnall         return "The complexity of an attempted match against a regular "
497a984708SDavid Chisnall                "expression exceeded a pre-set level.";
507a984708SDavid Chisnall     case regex_constants::error_stack:
517a984708SDavid Chisnall         return "There was insufficient memory to determine whether the regular "
527a984708SDavid Chisnall                "expression could match the specified character sequence.";
537a984708SDavid Chisnall     case regex_constants::__re_err_grammar:
547a984708SDavid Chisnall         return "An invalid regex grammar has been requested.";
557a984708SDavid Chisnall     case regex_constants::__re_err_empty:
567a984708SDavid Chisnall         return "An empty regex is not allowed in the POSIX grammar.";
577a984708SDavid Chisnall     default:
587a984708SDavid Chisnall         break;
597a984708SDavid Chisnall     }
607a984708SDavid Chisnall     return "Unknown error type";
617a984708SDavid Chisnall }
627a984708SDavid Chisnall 
regex_error(regex_constants::error_type ecode)637a984708SDavid Chisnall regex_error::regex_error(regex_constants::error_type ecode)
647a984708SDavid Chisnall     : runtime_error(make_error_type_string(ecode)),
657a984708SDavid Chisnall       __code_(ecode)
667a984708SDavid Chisnall {}
677a984708SDavid Chisnall 
~regex_error()687a984708SDavid Chisnall regex_error::~regex_error() throw() {}
697a984708SDavid Chisnall 
707a984708SDavid Chisnall namespace {
717a984708SDavid Chisnall 
727a984708SDavid Chisnall struct collationnames
737a984708SDavid Chisnall {
747a984708SDavid Chisnall     const char* elem_;
757a984708SDavid Chisnall     char char_;
767a984708SDavid Chisnall };
777a984708SDavid Chisnall 
787a984708SDavid Chisnall const collationnames collatenames[] =
797a984708SDavid Chisnall {
807a984708SDavid Chisnall     {"A", 0x41},
817a984708SDavid Chisnall     {"B", 0x42},
827a984708SDavid Chisnall     {"C", 0x43},
837a984708SDavid Chisnall     {"D", 0x44},
847a984708SDavid Chisnall     {"E", 0x45},
857a984708SDavid Chisnall     {"F", 0x46},
867a984708SDavid Chisnall     {"G", 0x47},
877a984708SDavid Chisnall     {"H", 0x48},
887a984708SDavid Chisnall     {"I", 0x49},
897a984708SDavid Chisnall     {"J", 0x4a},
907a984708SDavid Chisnall     {"K", 0x4b},
917a984708SDavid Chisnall     {"L", 0x4c},
927a984708SDavid Chisnall     {"M", 0x4d},
937a984708SDavid Chisnall     {"N", 0x4e},
947a984708SDavid Chisnall     {"NUL", 0x00},
957a984708SDavid Chisnall     {"O", 0x4f},
967a984708SDavid Chisnall     {"P", 0x50},
977a984708SDavid Chisnall     {"Q", 0x51},
987a984708SDavid Chisnall     {"R", 0x52},
997a984708SDavid Chisnall     {"S", 0x53},
1007a984708SDavid Chisnall     {"T", 0x54},
1017a984708SDavid Chisnall     {"U", 0x55},
1027a984708SDavid Chisnall     {"V", 0x56},
1037a984708SDavid Chisnall     {"W", 0x57},
1047a984708SDavid Chisnall     {"X", 0x58},
1057a984708SDavid Chisnall     {"Y", 0x59},
1067a984708SDavid Chisnall     {"Z", 0x5a},
1077a984708SDavid Chisnall     {"a", 0x61},
1087a984708SDavid Chisnall     {"alert", 0x07},
1097a984708SDavid Chisnall     {"ampersand", 0x26},
1107a984708SDavid Chisnall     {"apostrophe", 0x27},
1117a984708SDavid Chisnall     {"asterisk", 0x2a},
1127a984708SDavid Chisnall     {"b", 0x62},
1137a984708SDavid Chisnall     {"backslash", 0x5c},
1147a984708SDavid Chisnall     {"backspace", 0x08},
1157a984708SDavid Chisnall     {"c", 0x63},
1167a984708SDavid Chisnall     {"carriage-return", 0x0d},
1177a984708SDavid Chisnall     {"circumflex", 0x5e},
1187a984708SDavid Chisnall     {"circumflex-accent", 0x5e},
1197a984708SDavid Chisnall     {"colon", 0x3a},
1207a984708SDavid Chisnall     {"comma", 0x2c},
1217a984708SDavid Chisnall     {"commercial-at", 0x40},
1227a984708SDavid Chisnall     {"d", 0x64},
1237a984708SDavid Chisnall     {"dollar-sign", 0x24},
1247a984708SDavid Chisnall     {"e", 0x65},
1257a984708SDavid Chisnall     {"eight", 0x38},
1267a984708SDavid Chisnall     {"equals-sign", 0x3d},
1277a984708SDavid Chisnall     {"exclamation-mark", 0x21},
1287a984708SDavid Chisnall     {"f", 0x66},
1297a984708SDavid Chisnall     {"five", 0x35},
1307a984708SDavid Chisnall     {"form-feed", 0x0c},
1317a984708SDavid Chisnall     {"four", 0x34},
1327a984708SDavid Chisnall     {"full-stop", 0x2e},
1337a984708SDavid Chisnall     {"g", 0x67},
1347a984708SDavid Chisnall     {"grave-accent", 0x60},
1357a984708SDavid Chisnall     {"greater-than-sign", 0x3e},
1367a984708SDavid Chisnall     {"h", 0x68},
1377a984708SDavid Chisnall     {"hyphen", 0x2d},
1387a984708SDavid Chisnall     {"hyphen-minus", 0x2d},
1397a984708SDavid Chisnall     {"i", 0x69},
1407a984708SDavid Chisnall     {"j", 0x6a},
1417a984708SDavid Chisnall     {"k", 0x6b},
1427a984708SDavid Chisnall     {"l", 0x6c},
1437a984708SDavid Chisnall     {"left-brace", 0x7b},
1447a984708SDavid Chisnall     {"left-curly-bracket", 0x7b},
1457a984708SDavid Chisnall     {"left-parenthesis", 0x28},
1467a984708SDavid Chisnall     {"left-square-bracket", 0x5b},
1477a984708SDavid Chisnall     {"less-than-sign", 0x3c},
1487a984708SDavid Chisnall     {"low-line", 0x5f},
1497a984708SDavid Chisnall     {"m", 0x6d},
1507a984708SDavid Chisnall     {"n", 0x6e},
1517a984708SDavid Chisnall     {"newline", 0x0a},
1527a984708SDavid Chisnall     {"nine", 0x39},
1537a984708SDavid Chisnall     {"number-sign", 0x23},
1547a984708SDavid Chisnall     {"o", 0x6f},
1557a984708SDavid Chisnall     {"one", 0x31},
1567a984708SDavid Chisnall     {"p", 0x70},
1577a984708SDavid Chisnall     {"percent-sign", 0x25},
1587a984708SDavid Chisnall     {"period", 0x2e},
1597a984708SDavid Chisnall     {"plus-sign", 0x2b},
1607a984708SDavid Chisnall     {"q", 0x71},
1617a984708SDavid Chisnall     {"question-mark", 0x3f},
1627a984708SDavid Chisnall     {"quotation-mark", 0x22},
1637a984708SDavid Chisnall     {"r", 0x72},
1647a984708SDavid Chisnall     {"reverse-solidus", 0x5c},
1657a984708SDavid Chisnall     {"right-brace", 0x7d},
1667a984708SDavid Chisnall     {"right-curly-bracket", 0x7d},
1677a984708SDavid Chisnall     {"right-parenthesis", 0x29},
1687a984708SDavid Chisnall     {"right-square-bracket", 0x5d},
1697a984708SDavid Chisnall     {"s", 0x73},
1707a984708SDavid Chisnall     {"semicolon", 0x3b},
1717a984708SDavid Chisnall     {"seven", 0x37},
1727a984708SDavid Chisnall     {"six", 0x36},
1737a984708SDavid Chisnall     {"slash", 0x2f},
1747a984708SDavid Chisnall     {"solidus", 0x2f},
1757a984708SDavid Chisnall     {"space", 0x20},
1767a984708SDavid Chisnall     {"t", 0x74},
1777a984708SDavid Chisnall     {"tab", 0x09},
1787a984708SDavid Chisnall     {"three", 0x33},
1797a984708SDavid Chisnall     {"tilde", 0x7e},
1807a984708SDavid Chisnall     {"two", 0x32},
1817a984708SDavid Chisnall     {"u", 0x75},
1827a984708SDavid Chisnall     {"underscore", 0x5f},
1837a984708SDavid Chisnall     {"v", 0x76},
1847a984708SDavid Chisnall     {"vertical-line", 0x7c},
1857a984708SDavid Chisnall     {"vertical-tab", 0x0b},
1867a984708SDavid Chisnall     {"w", 0x77},
1877a984708SDavid Chisnall     {"x", 0x78},
1887a984708SDavid Chisnall     {"y", 0x79},
1897a984708SDavid Chisnall     {"z", 0x7a},
1907a984708SDavid Chisnall     {"zero", 0x30}
1917a984708SDavid Chisnall };
1927a984708SDavid Chisnall 
1937a984708SDavid Chisnall struct classnames
1947a984708SDavid Chisnall {
1957a984708SDavid Chisnall     const char* elem_;
196*d72607e9SDimitry Andric     regex_traits<char>::char_class_type mask_;
1977a984708SDavid Chisnall };
1987a984708SDavid Chisnall 
1997a984708SDavid Chisnall const classnames ClassNames[] =
2007a984708SDavid Chisnall {
2017a984708SDavid Chisnall     {"alnum",  ctype_base::alnum},
2027a984708SDavid Chisnall     {"alpha",  ctype_base::alpha},
2037a984708SDavid Chisnall     {"blank",  ctype_base::blank},
2047a984708SDavid Chisnall     {"cntrl",  ctype_base::cntrl},
2057a984708SDavid Chisnall     {"d",      ctype_base::digit},
2067a984708SDavid Chisnall     {"digit",  ctype_base::digit},
2077a984708SDavid Chisnall     {"graph",  ctype_base::graph},
2087a984708SDavid Chisnall     {"lower",  ctype_base::lower},
2097a984708SDavid Chisnall     {"print",  ctype_base::print},
2107a984708SDavid Chisnall     {"punct",  ctype_base::punct},
2117a984708SDavid Chisnall     {"s",      ctype_base::space},
2127a984708SDavid Chisnall     {"space",  ctype_base::space},
2137a984708SDavid Chisnall     {"upper",  ctype_base::upper},
2147a984708SDavid Chisnall     {"w",      regex_traits<char>::__regex_word},
2157a984708SDavid Chisnall     {"xdigit", ctype_base::xdigit}
2167a984708SDavid Chisnall };
2177a984708SDavid Chisnall 
2187a984708SDavid Chisnall struct use_strcmp
2197a984708SDavid Chisnall {
operator ()__anon97199a360111::use_strcmp2207a984708SDavid Chisnall     bool operator()(const collationnames& x, const char* y)
2217a984708SDavid Chisnall         {return strcmp(x.elem_, y) < 0;}
operator ()__anon97199a360111::use_strcmp2227a984708SDavid Chisnall     bool operator()(const classnames& x, const char* y)
2237a984708SDavid Chisnall         {return strcmp(x.elem_, y) < 0;}
2247a984708SDavid Chisnall };
2257a984708SDavid Chisnall 
2267a984708SDavid Chisnall }
2277a984708SDavid Chisnall 
2287a984708SDavid Chisnall string
__get_collation_name(const char * s)2297a984708SDavid Chisnall __get_collation_name(const char* s)
2307a984708SDavid Chisnall {
2317a984708SDavid Chisnall     const collationnames* i =
2327a984708SDavid Chisnall             _VSTD::lower_bound(begin(collatenames), end(collatenames), s, use_strcmp());
2337a984708SDavid Chisnall     string r;
2347a984708SDavid Chisnall     if (i != end(collatenames) && strcmp(s, i->elem_) == 0)
2357a984708SDavid Chisnall         r = char(i->char_);
2367a984708SDavid Chisnall     return r;
2377a984708SDavid Chisnall }
2387a984708SDavid Chisnall 
239*d72607e9SDimitry Andric regex_traits<char>::char_class_type
__get_classname(const char * s,bool __icase)2407a984708SDavid Chisnall __get_classname(const char* s, bool __icase)
2417a984708SDavid Chisnall {
2427a984708SDavid Chisnall     const classnames* i =
2437a984708SDavid Chisnall             _VSTD::lower_bound(begin(ClassNames), end(ClassNames), s, use_strcmp());
244*d72607e9SDimitry Andric     regex_traits<char>::char_class_type r = 0;
2457a984708SDavid Chisnall     if (i != end(ClassNames) && strcmp(s, i->elem_) == 0)
2467a984708SDavid Chisnall     {
2477a984708SDavid Chisnall         r = i->mask_;
2487a984708SDavid Chisnall         if (r == regex_traits<char>::__regex_word)
2497a984708SDavid Chisnall             r |= ctype_base::alnum | ctype_base::upper | ctype_base::lower;
2507a984708SDavid Chisnall         else if (__icase)
2517a984708SDavid Chisnall         {
2527a984708SDavid Chisnall             if (r & (ctype_base::lower | ctype_base::upper))
2537a984708SDavid Chisnall                 r |= ctype_base::alpha;
2547a984708SDavid Chisnall         }
2557a984708SDavid Chisnall     }
2567a984708SDavid Chisnall     return r;
2577a984708SDavid Chisnall }
2587a984708SDavid Chisnall 
2597a984708SDavid Chisnall template <>
2607a984708SDavid Chisnall void
__exec(__state & __s) const2617a984708SDavid Chisnall __match_any_but_newline<char>::__exec(__state& __s) const
2627a984708SDavid Chisnall {
2637a984708SDavid Chisnall     if (__s.__current_ != __s.__last_)
2647a984708SDavid Chisnall     {
2657a984708SDavid Chisnall         switch (*__s.__current_)
2667a984708SDavid Chisnall         {
2677a984708SDavid Chisnall         case '\r':
2687a984708SDavid Chisnall         case '\n':
2697a984708SDavid Chisnall             __s.__do_ = __state::__reject;
2707a984708SDavid Chisnall             __s.__node_ = nullptr;
2717a984708SDavid Chisnall             break;
2727a984708SDavid Chisnall         default:
2737a984708SDavid Chisnall             __s.__do_ = __state::__accept_and_consume;
2747a984708SDavid Chisnall             ++__s.__current_;
2757a984708SDavid Chisnall             __s.__node_ = this->first();
2767a984708SDavid Chisnall             break;
2777a984708SDavid Chisnall         }
2787a984708SDavid Chisnall     }
2797a984708SDavid Chisnall     else
2807a984708SDavid Chisnall     {
2817a984708SDavid Chisnall         __s.__do_ = __state::__reject;
2827a984708SDavid Chisnall         __s.__node_ = nullptr;
2837a984708SDavid Chisnall     }
2847a984708SDavid Chisnall }
2857a984708SDavid Chisnall 
2867a984708SDavid Chisnall template <>
2877a984708SDavid Chisnall void
__exec(__state & __s) const2887a984708SDavid Chisnall __match_any_but_newline<wchar_t>::__exec(__state& __s) const
2897a984708SDavid Chisnall {
2907a984708SDavid Chisnall     if (__s.__current_ != __s.__last_)
2917a984708SDavid Chisnall     {
2927a984708SDavid Chisnall         switch (*__s.__current_)
2937a984708SDavid Chisnall         {
2947a984708SDavid Chisnall         case '\r':
2957a984708SDavid Chisnall         case '\n':
2967a984708SDavid Chisnall         case 0x2028:
2977a984708SDavid Chisnall         case 0x2029:
2987a984708SDavid Chisnall             __s.__do_ = __state::__reject;
2997a984708SDavid Chisnall             __s.__node_ = nullptr;
3007a984708SDavid Chisnall             break;
3017a984708SDavid Chisnall         default:
3027a984708SDavid Chisnall             __s.__do_ = __state::__accept_and_consume;
3037a984708SDavid Chisnall             ++__s.__current_;
3047a984708SDavid Chisnall             __s.__node_ = this->first();
3057a984708SDavid Chisnall             break;
3067a984708SDavid Chisnall         }
3077a984708SDavid Chisnall     }
3087a984708SDavid Chisnall     else
3097a984708SDavid Chisnall     {
3107a984708SDavid Chisnall         __s.__do_ = __state::__reject;
3117a984708SDavid Chisnall         __s.__node_ = nullptr;
3127a984708SDavid Chisnall     }
3137a984708SDavid Chisnall }
3147a984708SDavid Chisnall 
3157a984708SDavid Chisnall _LIBCPP_END_NAMESPACE_STD
316