170505305SHoward Hinnant //===-------------------------- regex.cpp ---------------------------------===// 270505305SHoward Hinnant // 370505305SHoward Hinnant // The LLVM Compiler Infrastructure 470505305SHoward Hinnant // 5412dbebeSHoward Hinnant // This file is dual licensed under the MIT and the University of Illinois Open 6412dbebeSHoward Hinnant // Source Licenses. See LICENSE.TXT for details. 770505305SHoward Hinnant // 870505305SHoward Hinnant //===----------------------------------------------------------------------===// 970505305SHoward Hinnant 1070505305SHoward Hinnant #include "regex" 1170505305SHoward Hinnant #include "algorithm" 1270505305SHoward Hinnant #include "iterator" 1370505305SHoward Hinnant 1470505305SHoward Hinnant _LIBCPP_BEGIN_NAMESPACE_STD 1570505305SHoward Hinnant 1670505305SHoward Hinnant static 1770505305SHoward Hinnant const char* 1870505305SHoward Hinnant make_error_type_string(regex_constants::error_type ecode) 1970505305SHoward Hinnant { 2070505305SHoward Hinnant switch (ecode) 2170505305SHoward Hinnant { 2270505305SHoward Hinnant case regex_constants::error_collate: 2324e98486SHoward Hinnant return "The expression contained an invalid collating element name."; 2470505305SHoward Hinnant case regex_constants::error_ctype: 2524e98486SHoward Hinnant return "The expression contained an invalid character class name."; 2670505305SHoward Hinnant case regex_constants::error_escape: 2724e98486SHoward Hinnant return "The expression contained an invalid escaped character, or a " 2824e98486SHoward Hinnant "trailing escape."; 2970505305SHoward Hinnant case regex_constants::error_backref: 3024e98486SHoward Hinnant return "The expression contained an invalid back reference."; 3170505305SHoward Hinnant case regex_constants::error_brack: 3224e98486SHoward Hinnant return "The expression contained mismatched [ and ]."; 3370505305SHoward Hinnant case regex_constants::error_paren: 3424e98486SHoward Hinnant return "The expression contained mismatched ( and )."; 3570505305SHoward Hinnant case regex_constants::error_brace: 3624e98486SHoward Hinnant return "The expression contained mismatched { and }."; 3770505305SHoward Hinnant case regex_constants::error_badbrace: 3824e98486SHoward Hinnant return "The expression contained an invalid range in a {} expression."; 3970505305SHoward Hinnant case regex_constants::error_range: 4024e98486SHoward Hinnant return "The expression contained an invalid character range, " 4124e98486SHoward Hinnant "such as [b-a] in most encodings."; 4270505305SHoward Hinnant case regex_constants::error_space: 4324e98486SHoward Hinnant return "There was insufficient memory to convert the expression into " 4424e98486SHoward Hinnant "a finite state machine."; 4570505305SHoward Hinnant case regex_constants::error_badrepeat: 4624e98486SHoward Hinnant return "One of *?+{ was not preceded by a valid regular expression."; 4770505305SHoward Hinnant case regex_constants::error_complexity: 4824e98486SHoward Hinnant return "The complexity of an attempted match against a regular " 4924e98486SHoward Hinnant "expression exceeded a pre-set level."; 5070505305SHoward Hinnant case regex_constants::error_stack: 5124e98486SHoward Hinnant return "There was insufficient memory to determine whether the regular " 5224e98486SHoward Hinnant "expression could match the specified character sequence."; 536afe8b0aSHoward Hinnant case regex_constants::__re_err_grammar: 546afe8b0aSHoward Hinnant return "An invalid regex grammar has been requested."; 556afe8b0aSHoward Hinnant case regex_constants::__re_err_empty: 566afe8b0aSHoward Hinnant return "An empty regex is not allowed in the POSIX grammar."; 5724e98486SHoward Hinnant default: 5824e98486SHoward Hinnant break; 5970505305SHoward Hinnant } 6024e98486SHoward Hinnant return "Unknown error type"; 6170505305SHoward Hinnant } 6270505305SHoward Hinnant 6370505305SHoward Hinnant regex_error::regex_error(regex_constants::error_type ecode) 6470505305SHoward Hinnant : runtime_error(make_error_type_string(ecode)), 6570505305SHoward Hinnant __code_(ecode) 6670505305SHoward Hinnant {} 6770505305SHoward Hinnant 6870505305SHoward Hinnant regex_error::~regex_error() throw() {} 6970505305SHoward Hinnant 7070505305SHoward Hinnant namespace { 7170505305SHoward Hinnant 72*b0d5be56SLogan Chien #if defined(__clang__) 73c206366fSHoward Hinnant #pragma clang diagnostic push 74c206366fSHoward Hinnant #pragma clang diagnostic ignored "-Wpadded" 75*b0d5be56SLogan Chien #endif 76c206366fSHoward Hinnant 7770505305SHoward Hinnant struct collationnames 7870505305SHoward Hinnant { 7970505305SHoward Hinnant const char* elem_; 8070505305SHoward Hinnant char char_; 8170505305SHoward Hinnant }; 8270505305SHoward Hinnant 83*b0d5be56SLogan Chien #if defined(__clang__) 84c206366fSHoward Hinnant #pragma clang diagnostic pop 85*b0d5be56SLogan Chien #endif 86c206366fSHoward Hinnant 8770505305SHoward Hinnant const collationnames collatenames[] = 8870505305SHoward Hinnant { 8970505305SHoward Hinnant {"A", 0x41}, 9070505305SHoward Hinnant {"B", 0x42}, 9170505305SHoward Hinnant {"C", 0x43}, 9270505305SHoward Hinnant {"D", 0x44}, 9370505305SHoward Hinnant {"E", 0x45}, 9470505305SHoward Hinnant {"F", 0x46}, 9570505305SHoward Hinnant {"G", 0x47}, 9670505305SHoward Hinnant {"H", 0x48}, 9770505305SHoward Hinnant {"I", 0x49}, 9870505305SHoward Hinnant {"J", 0x4a}, 9970505305SHoward Hinnant {"K", 0x4b}, 10070505305SHoward Hinnant {"L", 0x4c}, 10170505305SHoward Hinnant {"M", 0x4d}, 10270505305SHoward Hinnant {"N", 0x4e}, 10370505305SHoward Hinnant {"NUL", 0x00}, 10470505305SHoward Hinnant {"O", 0x4f}, 10570505305SHoward Hinnant {"P", 0x50}, 10670505305SHoward Hinnant {"Q", 0x51}, 10770505305SHoward Hinnant {"R", 0x52}, 10870505305SHoward Hinnant {"S", 0x53}, 10970505305SHoward Hinnant {"T", 0x54}, 11070505305SHoward Hinnant {"U", 0x55}, 11170505305SHoward Hinnant {"V", 0x56}, 11270505305SHoward Hinnant {"W", 0x57}, 11370505305SHoward Hinnant {"X", 0x58}, 11470505305SHoward Hinnant {"Y", 0x59}, 11570505305SHoward Hinnant {"Z", 0x5a}, 11670505305SHoward Hinnant {"a", 0x61}, 11770505305SHoward Hinnant {"alert", 0x07}, 11870505305SHoward Hinnant {"ampersand", 0x26}, 11970505305SHoward Hinnant {"apostrophe", 0x27}, 12070505305SHoward Hinnant {"asterisk", 0x2a}, 12170505305SHoward Hinnant {"b", 0x62}, 12270505305SHoward Hinnant {"backslash", 0x5c}, 12370505305SHoward Hinnant {"backspace", 0x08}, 12470505305SHoward Hinnant {"c", 0x63}, 12570505305SHoward Hinnant {"carriage-return", 0x0d}, 12670505305SHoward Hinnant {"circumflex", 0x5e}, 12770505305SHoward Hinnant {"circumflex-accent", 0x5e}, 12870505305SHoward Hinnant {"colon", 0x3a}, 12970505305SHoward Hinnant {"comma", 0x2c}, 13070505305SHoward Hinnant {"commercial-at", 0x40}, 13170505305SHoward Hinnant {"d", 0x64}, 13270505305SHoward Hinnant {"dollar-sign", 0x24}, 13370505305SHoward Hinnant {"e", 0x65}, 13470505305SHoward Hinnant {"eight", 0x38}, 13570505305SHoward Hinnant {"equals-sign", 0x3d}, 13670505305SHoward Hinnant {"exclamation-mark", 0x21}, 13770505305SHoward Hinnant {"f", 0x66}, 13870505305SHoward Hinnant {"five", 0x35}, 13970505305SHoward Hinnant {"form-feed", 0x0c}, 14070505305SHoward Hinnant {"four", 0x34}, 14170505305SHoward Hinnant {"full-stop", 0x2e}, 14270505305SHoward Hinnant {"g", 0x67}, 14370505305SHoward Hinnant {"grave-accent", 0x60}, 14470505305SHoward Hinnant {"greater-than-sign", 0x3e}, 14570505305SHoward Hinnant {"h", 0x68}, 14670505305SHoward Hinnant {"hyphen", 0x2d}, 14770505305SHoward Hinnant {"hyphen-minus", 0x2d}, 14870505305SHoward Hinnant {"i", 0x69}, 14970505305SHoward Hinnant {"j", 0x6a}, 15070505305SHoward Hinnant {"k", 0x6b}, 15170505305SHoward Hinnant {"l", 0x6c}, 15270505305SHoward Hinnant {"left-brace", 0x7b}, 15370505305SHoward Hinnant {"left-curly-bracket", 0x7b}, 15470505305SHoward Hinnant {"left-parenthesis", 0x28}, 15570505305SHoward Hinnant {"left-square-bracket", 0x5b}, 15670505305SHoward Hinnant {"less-than-sign", 0x3c}, 15770505305SHoward Hinnant {"low-line", 0x5f}, 15870505305SHoward Hinnant {"m", 0x6d}, 15970505305SHoward Hinnant {"n", 0x6e}, 16070505305SHoward Hinnant {"newline", 0x0a}, 16170505305SHoward Hinnant {"nine", 0x39}, 16270505305SHoward Hinnant {"number-sign", 0x23}, 16370505305SHoward Hinnant {"o", 0x6f}, 16470505305SHoward Hinnant {"one", 0x31}, 16570505305SHoward Hinnant {"p", 0x70}, 16670505305SHoward Hinnant {"percent-sign", 0x25}, 16770505305SHoward Hinnant {"period", 0x2e}, 16870505305SHoward Hinnant {"plus-sign", 0x2b}, 16970505305SHoward Hinnant {"q", 0x71}, 17070505305SHoward Hinnant {"question-mark", 0x3f}, 17170505305SHoward Hinnant {"quotation-mark", 0x22}, 17270505305SHoward Hinnant {"r", 0x72}, 17370505305SHoward Hinnant {"reverse-solidus", 0x5c}, 17470505305SHoward Hinnant {"right-brace", 0x7d}, 17570505305SHoward Hinnant {"right-curly-bracket", 0x7d}, 17670505305SHoward Hinnant {"right-parenthesis", 0x29}, 17770505305SHoward Hinnant {"right-square-bracket", 0x5d}, 17870505305SHoward Hinnant {"s", 0x73}, 17970505305SHoward Hinnant {"semicolon", 0x3b}, 18070505305SHoward Hinnant {"seven", 0x37}, 18170505305SHoward Hinnant {"six", 0x36}, 18270505305SHoward Hinnant {"slash", 0x2f}, 18370505305SHoward Hinnant {"solidus", 0x2f}, 18470505305SHoward Hinnant {"space", 0x20}, 18570505305SHoward Hinnant {"t", 0x74}, 18670505305SHoward Hinnant {"tab", 0x09}, 18770505305SHoward Hinnant {"three", 0x33}, 18870505305SHoward Hinnant {"tilde", 0x7e}, 18970505305SHoward Hinnant {"two", 0x32}, 19070505305SHoward Hinnant {"u", 0x75}, 19170505305SHoward Hinnant {"underscore", 0x5f}, 19270505305SHoward Hinnant {"v", 0x76}, 19370505305SHoward Hinnant {"vertical-line", 0x7c}, 19470505305SHoward Hinnant {"vertical-tab", 0x0b}, 19570505305SHoward Hinnant {"w", 0x77}, 19670505305SHoward Hinnant {"x", 0x78}, 19770505305SHoward Hinnant {"y", 0x79}, 19870505305SHoward Hinnant {"z", 0x7a}, 19970505305SHoward Hinnant {"zero", 0x30} 20070505305SHoward Hinnant }; 20170505305SHoward Hinnant 202*b0d5be56SLogan Chien #if defined(__clang__) 203c206366fSHoward Hinnant #pragma clang diagnostic push 204c206366fSHoward Hinnant #pragma clang diagnostic ignored "-Wpadded" 205*b0d5be56SLogan Chien #endif 206c206366fSHoward Hinnant 20724757ff7SHoward Hinnant struct classnames 20824757ff7SHoward Hinnant { 20924757ff7SHoward Hinnant const char* elem_; 21024757ff7SHoward Hinnant ctype_base::mask mask_; 21124757ff7SHoward Hinnant }; 21224757ff7SHoward Hinnant 213*b0d5be56SLogan Chien #if defined(__clang__) 214c206366fSHoward Hinnant #pragma clang diagnostic pop 215*b0d5be56SLogan Chien #endif 216c206366fSHoward Hinnant 21724757ff7SHoward Hinnant const classnames ClassNames[] = 21824757ff7SHoward Hinnant { 21924757ff7SHoward Hinnant {"alnum", ctype_base::alnum}, 22024757ff7SHoward Hinnant {"alpha", ctype_base::alpha}, 22124757ff7SHoward Hinnant {"blank", ctype_base::blank}, 22224757ff7SHoward Hinnant {"cntrl", ctype_base::cntrl}, 22324757ff7SHoward Hinnant {"d", ctype_base::digit}, 22424757ff7SHoward Hinnant {"digit", ctype_base::digit}, 22524757ff7SHoward Hinnant {"graph", ctype_base::graph}, 22624757ff7SHoward Hinnant {"lower", ctype_base::lower}, 22724757ff7SHoward Hinnant {"print", ctype_base::print}, 22824757ff7SHoward Hinnant {"punct", ctype_base::punct}, 22924757ff7SHoward Hinnant {"s", ctype_base::space}, 23024757ff7SHoward Hinnant {"space", ctype_base::space}, 23124757ff7SHoward Hinnant {"upper", ctype_base::upper}, 23224757ff7SHoward Hinnant {"w", regex_traits<char>::__regex_word}, 23324757ff7SHoward Hinnant {"xdigit", ctype_base::xdigit} 23424757ff7SHoward Hinnant }; 23524757ff7SHoward Hinnant 23670505305SHoward Hinnant struct use_strcmp 23770505305SHoward Hinnant { 23870505305SHoward Hinnant bool operator()(const collationnames& x, const char* y) 23970505305SHoward Hinnant {return strcmp(x.elem_, y) < 0;} 24024757ff7SHoward Hinnant bool operator()(const classnames& x, const char* y) 24124757ff7SHoward Hinnant {return strcmp(x.elem_, y) < 0;} 24270505305SHoward Hinnant }; 24370505305SHoward Hinnant 24470505305SHoward Hinnant } 24570505305SHoward Hinnant 24670505305SHoward Hinnant string 24770505305SHoward Hinnant __get_collation_name(const char* s) 24870505305SHoward Hinnant { 24970505305SHoward Hinnant const collationnames* i = 250ce48a113SHoward Hinnant _VSTD::lower_bound(begin(collatenames), end(collatenames), s, use_strcmp()); 25170505305SHoward Hinnant string r; 25270505305SHoward Hinnant if (i != end(collatenames) && strcmp(s, i->elem_) == 0) 25370505305SHoward Hinnant r = char(i->char_); 25470505305SHoward Hinnant return r; 25570505305SHoward Hinnant } 25670505305SHoward Hinnant 25724757ff7SHoward Hinnant ctype_base::mask 25824757ff7SHoward Hinnant __get_classname(const char* s, bool __icase) 25924757ff7SHoward Hinnant { 26024757ff7SHoward Hinnant const classnames* i = 261ce48a113SHoward Hinnant _VSTD::lower_bound(begin(ClassNames), end(ClassNames), s, use_strcmp()); 26224757ff7SHoward Hinnant ctype_base::mask r = 0; 26324757ff7SHoward Hinnant if (i != end(ClassNames) && strcmp(s, i->elem_) == 0) 26424757ff7SHoward Hinnant { 26524757ff7SHoward Hinnant r = i->mask_; 26624757ff7SHoward Hinnant if (r == regex_traits<char>::__regex_word) 26724757ff7SHoward Hinnant r |= ctype_base::alnum | ctype_base::upper | ctype_base::lower; 26824757ff7SHoward Hinnant else if (__icase) 26924757ff7SHoward Hinnant { 27024757ff7SHoward Hinnant if (r & (ctype_base::lower | ctype_base::upper)) 27124757ff7SHoward Hinnant r |= ctype_base::alpha; 27224757ff7SHoward Hinnant } 27324757ff7SHoward Hinnant } 27424757ff7SHoward Hinnant return r; 27524757ff7SHoward Hinnant } 27624757ff7SHoward Hinnant 2775c679861SHoward Hinnant template <> 2785c679861SHoward Hinnant void 2795c679861SHoward Hinnant __match_any_but_newline<char>::__exec(__state& __s) const 2805c679861SHoward Hinnant { 2815c679861SHoward Hinnant if (__s.__current_ != __s.__last_) 2825c679861SHoward Hinnant { 2835c679861SHoward Hinnant switch (*__s.__current_) 2845c679861SHoward Hinnant { 2855c679861SHoward Hinnant case '\r': 2865c679861SHoward Hinnant case '\n': 2875c679861SHoward Hinnant __s.__do_ = __state::__reject; 2885c679861SHoward Hinnant __s.__node_ = nullptr; 2895c679861SHoward Hinnant break; 2905c679861SHoward Hinnant default: 2915c679861SHoward Hinnant __s.__do_ = __state::__accept_and_consume; 2925c679861SHoward Hinnant ++__s.__current_; 2935c679861SHoward Hinnant __s.__node_ = this->first(); 2945c679861SHoward Hinnant break; 2955c679861SHoward Hinnant } 2965c679861SHoward Hinnant } 2975c679861SHoward Hinnant else 2985c679861SHoward Hinnant { 2995c679861SHoward Hinnant __s.__do_ = __state::__reject; 3005c679861SHoward Hinnant __s.__node_ = nullptr; 3015c679861SHoward Hinnant } 3025c679861SHoward Hinnant } 3035c679861SHoward Hinnant 3045c679861SHoward Hinnant template <> 3055c679861SHoward Hinnant void 3065c679861SHoward Hinnant __match_any_but_newline<wchar_t>::__exec(__state& __s) const 3075c679861SHoward Hinnant { 3085c679861SHoward Hinnant if (__s.__current_ != __s.__last_) 3095c679861SHoward Hinnant { 3105c679861SHoward Hinnant switch (*__s.__current_) 3115c679861SHoward Hinnant { 3125c679861SHoward Hinnant case '\r': 3135c679861SHoward Hinnant case '\n': 3145c679861SHoward Hinnant case 0x2028: 3155c679861SHoward Hinnant case 0x2029: 3165c679861SHoward Hinnant __s.__do_ = __state::__reject; 3175c679861SHoward Hinnant __s.__node_ = nullptr; 3185c679861SHoward Hinnant break; 3195c679861SHoward Hinnant default: 3205c679861SHoward Hinnant __s.__do_ = __state::__accept_and_consume; 3215c679861SHoward Hinnant ++__s.__current_; 3225c679861SHoward Hinnant __s.__node_ = this->first(); 3235c679861SHoward Hinnant break; 3245c679861SHoward Hinnant } 3255c679861SHoward Hinnant } 3265c679861SHoward Hinnant else 3275c679861SHoward Hinnant { 3285c679861SHoward Hinnant __s.__do_ = __state::__reject; 3295c679861SHoward Hinnant __s.__node_ = nullptr; 3305c679861SHoward Hinnant } 3315c679861SHoward Hinnant } 3325c679861SHoward Hinnant 33370505305SHoward Hinnant _LIBCPP_END_NAMESPACE_STD 334