Executes the regexp program to search in text, which itself is inside the larger context. (As a convenience, passing a NULL context is equivalent to passing text.) Returns true if a match is found, false if not. If a match is found, fills in match0->end() to point at the end of the match and sets match0->begin() to text.begin(), since the DFA can't track where the match actually began. This is t
| 1820 | // This is the only external interface (class DFA only exists in this file). |
| 1821 | // |
| 1822 | bool Prog::SearchDFA(const StringPiece& text, const StringPiece& const_context, |
| 1823 | Anchor anchor, MatchKind kind, StringPiece* match0, |
| 1824 | bool* failed, SparseSet* matches) { |
| 1825 | *failed = false; |
| 1826 | |
| 1827 | StringPiece context = const_context; |
| 1828 | if (context.data() == NULL) |
| 1829 | context = text; |
| 1830 | bool caret = anchor_start(); |
| 1831 | bool dollar = anchor_end(); |
| 1832 | if (reversed_) { |
| 1833 | using std::swap; |
| 1834 | swap(caret, dollar); |
| 1835 | } |
| 1836 | if (caret && context.begin() != text.begin()) |
| 1837 | return false; |
| 1838 | if (dollar && context.end() != text.end()) |
| 1839 | return false; |
| 1840 | |
| 1841 | // Handle full match by running an anchored longest match |
| 1842 | // and then checking if it covers all of text. |
| 1843 | bool anchored = anchor == kAnchored || anchor_start() || kind == kFullMatch; |
| 1844 | bool endmatch = false; |
| 1845 | if (kind == kManyMatch) { |
| 1846 | // This is split out in order to avoid clobbering kind. |
| 1847 | } else if (kind == kFullMatch || anchor_end()) { |
| 1848 | endmatch = true; |
| 1849 | kind = kLongestMatch; |
| 1850 | } |
| 1851 | |
| 1852 | // If the caller doesn't care where the match is (just whether one exists), |
| 1853 | // then we can stop at the very first match we find, the so-called |
| 1854 | // "earliest match". |
| 1855 | bool want_earliest_match = false; |
| 1856 | if (kind == kManyMatch) { |
| 1857 | // This is split out in order to avoid clobbering kind. |
| 1858 | if (matches == NULL) { |
| 1859 | want_earliest_match = true; |
| 1860 | } |
| 1861 | } else if (match0 == NULL && !endmatch) { |
| 1862 | want_earliest_match = true; |
| 1863 | kind = kLongestMatch; |
| 1864 | } |
| 1865 | |
| 1866 | DFA* dfa = GetDFA(kind); |
| 1867 | const char* ep; |
| 1868 | bool matched = dfa->Search(text, context, anchored, |
| 1869 | want_earliest_match, !reversed_, |
| 1870 | failed, &ep, matches); |
| 1871 | if (*failed) { |
| 1872 | hooks::GetDFASearchFailureHook()({ |
| 1873 | // Nothing yet... |
| 1874 | }); |
| 1875 | return false; |
| 1876 | } |
| 1877 | if (!matched) |
| 1878 | return false; |
| 1879 | if (endmatch && ep != (reversed_ ? text.data() : text.data() + text.size())) |