| OLD | NEW |
| 1 // Copyright 2006 The RE2 Authors. All Rights Reserved. | 1 // Copyright 2006 The RE2 Authors. All Rights Reserved. |
| 2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
| 3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 // Regular expression representation. | 5 // Regular expression representation. |
| 6 // Tested by parse_test.cc | 6 // Tested by parse_test.cc |
| 7 | 7 |
| 8 #include "util/util.h" | 8 #include "util/util.h" |
| 9 #include "re2/regexp.h" | 9 #include "re2/regexp.h" |
| 10 #include "re2/stringpiece.h" | 10 #include "re2/stringpiece.h" |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 // If it's possible to destroy this regexp without recurring, | 52 // If it's possible to destroy this regexp without recurring, |
| 53 // do so and return true. Else return false. | 53 // do so and return true. Else return false. |
| 54 bool Regexp::QuickDestroy() { | 54 bool Regexp::QuickDestroy() { |
| 55 if (nsub_ == 0) { | 55 if (nsub_ == 0) { |
| 56 delete this; | 56 delete this; |
| 57 return true; | 57 return true; |
| 58 } | 58 } |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 static map<Regexp*, int> ref_map; | 62 static map<Regexp*, int> *ref_map; |
| 63 static Mutex ref_mutex; | 63 GLOBAL_MUTEX(ref_mutex); |
| 64 | 64 |
| 65 int Regexp::Ref() { | 65 int Regexp::Ref() { |
| 66 if (ref_ < kMaxRef) | 66 if (ref_ < kMaxRef) |
| 67 return ref_; | 67 return ref_; |
| 68 | 68 |
| 69 MutexLock l(&ref_mutex); | 69 GLOBAL_MUTEX_LOCK(ref_mutex); |
| 70 return ref_map[this]; | 70 int r = 0; |
| 71 if (ref_map != NULL) { |
| 72 r = (*ref_map)[this]; |
| 73 } |
| 74 GLOBAL_MUTEX_UNLOCK(ref_mutex); |
| 75 return r; |
| 71 } | 76 } |
| 72 | 77 |
| 73 // Increments reference count, returns object as convenience. | 78 // Increments reference count, returns object as convenience. |
| 74 Regexp* Regexp::Incref() { | 79 Regexp* Regexp::Incref() { |
| 75 if (ref_ >= kMaxRef-1) { | 80 if (ref_ >= kMaxRef-1) { |
| 76 // Store ref count in overflow map. | 81 // Store ref count in overflow map. |
| 77 MutexLock l(&ref_mutex); | 82 GLOBAL_MUTEX_LOCK(ref_mutex); |
| 78 if (ref_ == kMaxRef) { // already overflowed | 83 if (ref_map == NULL) { |
| 79 ref_map[this]++; | 84 ref_map = new map<Regexp*, int>; |
| 80 return this; | |
| 81 } | 85 } |
| 82 // overflowing now | 86 if (ref_ == kMaxRef) { |
| 83 ref_map[this] = kMaxRef; | 87 // already overflowed |
| 84 ref_ = kMaxRef; | 88 (*ref_map)[this]++; |
| 89 } else { |
| 90 // overflowing now |
| 91 (*ref_map)[this] = kMaxRef; |
| 92 ref_ = kMaxRef; |
| 93 } |
| 94 GLOBAL_MUTEX_UNLOCK(ref_mutex); |
| 85 return this; | 95 return this; |
| 86 } | 96 } |
| 87 | 97 |
| 88 ref_++; | 98 ref_++; |
| 89 return this; | 99 return this; |
| 90 } | 100 } |
| 91 | 101 |
| 92 // Decrements reference count and deletes this object if count reaches 0. | 102 // Decrements reference count and deletes this object if count reaches 0. |
| 93 void Regexp::Decref() { | 103 void Regexp::Decref() { |
| 94 if (ref_ == kMaxRef) { | 104 if (ref_ == kMaxRef) { |
| 95 // Ref count is stored in overflow map. | 105 // Ref count is stored in overflow map. |
| 96 MutexLock l(&ref_mutex); | 106 GLOBAL_MUTEX_LOCK(ref_mutex); |
| 97 int r = ref_map[this] - 1; | 107 int r = (*ref_map)[this] - 1; |
| 98 if (r < kMaxRef) { | 108 if (r < kMaxRef) { |
| 99 ref_ = r; | 109 ref_ = r; |
| 100 ref_map.erase(this); | 110 ref_map->erase(this); |
| 101 } else { | 111 } else { |
| 102 ref_map[this] = r; | 112 (*ref_map)[this] = r; |
| 103 } | 113 } |
| 114 GLOBAL_MUTEX_UNLOCK(ref_mutex); |
| 104 return; | 115 return; |
| 105 } | 116 } |
| 106 ref_--; | 117 ref_--; |
| 107 if (ref_ == 0) | 118 if (ref_ == 0) |
| 108 Destroy(); | 119 Destroy(); |
| 109 } | 120 } |
| 110 | 121 |
| 111 // Deletes this object; ref count has count reached 0. | 122 // Deletes this object; ref count has count reached 0. |
| 112 void Regexp::Destroy() { | 123 void Regexp::Destroy() { |
| 113 if (QuickDestroy()) | 124 if (QuickDestroy()) |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 | 451 |
| 441 a = stk[n-2]; | 452 a = stk[n-2]; |
| 442 b = stk[n-1]; | 453 b = stk[n-1]; |
| 443 stk.resize(n-2); | 454 stk.resize(n-2); |
| 444 } | 455 } |
| 445 | 456 |
| 446 return true; | 457 return true; |
| 447 } | 458 } |
| 448 | 459 |
| 449 // Keep in sync with enum RegexpStatusCode in regexp.h | 460 // Keep in sync with enum RegexpStatusCode in regexp.h |
| 450 static const string kErrorStrings[] = { | 461 static const char *kErrorStrings[] = { |
| 451 "no error", | 462 "no error", |
| 452 "unexpected error", | 463 "unexpected error", |
| 453 "invalid escape sequence", | 464 "invalid escape sequence", |
| 454 "invalid character class", | 465 "invalid character class", |
| 455 "invalid character class range", | 466 "invalid character class range", |
| 456 "missing ]", | 467 "missing ]", |
| 457 "missing )", | 468 "missing )", |
| 458 "trailing \\", | 469 "trailing \\", |
| 459 "no argument for repetition operator", | 470 "no argument for repetition operator", |
| 460 "invalid repetition size", | 471 "invalid repetition size", |
| 461 "bad repetition operator", | 472 "bad repetition operator", |
| 462 "invalid perl operator", | 473 "invalid perl operator", |
| 463 "invalid UTF-8", | 474 "invalid UTF-8", |
| 464 "invalid named capture group", | 475 "invalid named capture group", |
| 465 }; | 476 }; |
| 466 | 477 |
| 467 const string& RegexpStatus::CodeText(enum RegexpStatusCode code) { | 478 string RegexpStatus::CodeText(enum RegexpStatusCode code) { |
| 468 if (code < 0 || code >= arraysize(kErrorStrings)) | 479 if (code < 0 || code >= arraysize(kErrorStrings)) |
| 469 code = kRegexpInternalError; | 480 code = kRegexpInternalError; |
| 470 return kErrorStrings[code]; | 481 return kErrorStrings[code]; |
| 471 } | 482 } |
| 472 | 483 |
| 473 string RegexpStatus::Text() const { | 484 string RegexpStatus::Text() const { |
| 474 if (error_arg_.empty()) | 485 if (error_arg_.empty()) |
| 475 return CodeText(code_); | 486 return CodeText(code_); |
| 476 string s; | 487 string s; |
| 477 s.append(CodeText(code_)); | 488 s.append(CodeText(code_)); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 911 for (iterator it = begin(); it != end(); ++it) | 922 for (iterator it = begin(); it != end(); ++it) |
| 912 cc->ranges_[n++] = *it; | 923 cc->ranges_[n++] = *it; |
| 913 cc->nranges_ = n; | 924 cc->nranges_ = n; |
| 914 DCHECK_LE(n, ranges_.size()); | 925 DCHECK_LE(n, ranges_.size()); |
| 915 cc->nrunes_ = nrunes_; | 926 cc->nrunes_ = nrunes_; |
| 916 cc->folds_ascii_ = FoldsASCII(); | 927 cc->folds_ascii_ = FoldsASCII(); |
| 917 return cc; | 928 return cc; |
| 918 } | 929 } |
| 919 | 930 |
| 920 } // namespace re2 | 931 } // namespace re2 |
| OLD | NEW |