diff options
author | nyamatongwe <unknown> | 2003-03-04 10:53:59 +0000 |
---|---|---|
committer | nyamatongwe <unknown> | 2003-03-04 10:53:59 +0000 |
commit | 69daddeb2a241af212edca89f6a7422e6f8a5053 (patch) | |
tree | ab73038e7420a7a3902f38457b1635d8cb4fc676 | |
parent | 3767529b0e6cf365888cb7fe25e4a261116be830 (diff) | |
download | scintilla-mirror-69daddeb2a241af212edca89f6a7422e6f8a5053.tar.gz |
Patch from Jakub to optionally implement more POSIX compatible regular
expressions. \(..\) changes to (..)
Fixes problem where find previous would not find earlier matches on same
line.
-rw-r--r-- | include/Scintilla.h | 1 | ||||
-rw-r--r-- | include/Scintilla.iface | 1 | ||||
-rw-r--r-- | src/Document.cxx | 36 | ||||
-rw-r--r-- | src/Document.h | 2 | ||||
-rw-r--r-- | src/Editor.cxx | 6 | ||||
-rw-r--r-- | src/RESearch.cxx | 74 | ||||
-rw-r--r-- | src/RESearch.h | 2 |
7 files changed, 84 insertions, 38 deletions
diff --git a/include/Scintilla.h b/include/Scintilla.h index ecdda8de1..a04dc6c50 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -285,6 +285,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, #define SCFIND_MATCHCASE 4 #define SCFIND_WORDSTART 0x00100000 #define SCFIND_REGEXP 0x00200000 +#define SCFIND_POSIX 0x00400000 #define SCI_FINDTEXT 2150 #define SCI_FORMATRANGE 2151 #define SCI_GETFIRSTVISIBLELINE 2152 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 984b4a3d8..a0c73053e 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -701,6 +701,7 @@ val SCFIND_WHOLEWORD=2 val SCFIND_MATCHCASE=4 val SCFIND_WORDSTART=0x00100000 val SCFIND_REGEXP=0x00200000 +val SCFIND_POSIX=0x00400000 # Find some text in the document. fun position FindText=2150(int flags, findtext ft) diff --git a/src/Document.cxx b/src/Document.cxx index 20a53b132..a1d5beff6 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -847,7 +847,7 @@ public: * Has not been tested with backwards DBCS searches yet. */ long Document::FindText(int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, bool regExp, + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length) { if (regExp) { if (!pre) @@ -864,7 +864,7 @@ long Document::FindText(int minPos, int maxPos, const char *s, startPos = MovePositionOutsideChar(startPos, 1, false); endPos = MovePositionOutsideChar(endPos, 1, false); - const char *errmsg = pre->Compile(s, *length, caseSensitive); + const char *errmsg = pre->Compile(s, *length, caseSensitive, posix); if (errmsg) { return -1; } @@ -888,16 +888,30 @@ long Document::FindText(int minPos, int maxPos, const char *s, for (int line = lineRangeStart; line != lineRangeBreak; line += increment) { int startOfLine = LineStart(line); int endOfLine = LineEnd(line); - if ((increment == 1) && (line == lineRangeStart)) { - if ((startPos != startOfLine) && (s[0] == '^')) - continue; // Can't match start of line if start position after start of line - startOfLine = startPos; - } - if ((increment == 1) && (line == lineRangeEnd)) { - if ((endPos != endOfLine) && (searchEnd == '$')) - continue; // Can't match end of line if end position before end of line - endOfLine = endPos; + if (increment == 1) { + if (line == lineRangeStart) { + if ((startPos != startOfLine) && (s[0] == '^')) + continue; // Can't match start of line if start position after start of line + startOfLine = startPos; + } + if (line == lineRangeEnd) { + if ((endPos != endOfLine) && (searchEnd == '$')) + continue; // Can't match end of line if end position before end of line + endOfLine = endPos; + } + } else { + if (line == lineRangeEnd) { + if ((endPos != startOfLine) && (s[0] == '^')) + continue; // Can't match start of line if end position after start of line + startOfLine = endPos; + } + if (line == lineRangeStart) { + if ((startPos != endOfLine) && (searchEnd == '$')) + continue; // Can't match end of line if start position before end of line + endOfLine = startPos; + } } + DocumentIndexer di(this, endOfLine); int success = pre->Execute(di, startOfLine, endOfLine); if (success) { diff --git a/src/Document.h b/src/Document.h index 30fdc625e..597e33171 100644 --- a/src/Document.h +++ b/src/Document.h @@ -192,7 +192,7 @@ public: int NextWordStart(int pos, int delta); int Length() { return cb.Length(); } long FindText(int minPos, int maxPos, const char *s, - bool caseSensitive, bool word, bool wordStart, bool regExp, int *length); + bool caseSensitive, bool word, bool wordStart, bool regExp, bool posix, int *length); long FindText(int iMessage, unsigned long wParam, long lParam); const char *SubstituteByPosition(const char *text, int *length); int LinesTotal(); diff --git a/src/Editor.cxx b/src/Editor.cxx index b3509510d..7569d5a60 100644 --- a/src/Editor.cxx +++ b/src/Editor.cxx @@ -3988,7 +3988,7 @@ void Editor::Indent(bool forwards) { */ long Editor::FindText( uptr_t wParam, ///< Search modes : @c SCFIND_MATCHCASE, @c SCFIND_WHOLEWORD, - ///< @c SCFIND_WORDSTART or @c SCFIND_REGEXP. + ///< @c SCFIND_WORDSTART, @c SCFIND_REGEXP or @c SCFIND_POSIX. sptr_t lParam) { ///< @c TextToFind structure: The text to search for in the given range. TextToFind *ft = reinterpret_cast<TextToFind *>(lParam); @@ -3998,6 +3998,7 @@ long Editor::FindText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); if (pos != -1) { ft->chrgText.cpMin = pos; @@ -4041,6 +4042,7 @@ long Editor::SearchText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); } else { pos = pdoc->FindText(searchAnchor, 0, txt, @@ -4048,6 +4050,7 @@ long Editor::SearchText( (wParam & SCFIND_WHOLEWORD) != 0, (wParam & SCFIND_WORDSTART) != 0, (wParam & SCFIND_REGEXP) != 0, + (wParam & SCFIND_POSIX) != 0, &lengthFound); } @@ -4069,6 +4072,7 @@ long Editor::SearchInTarget(const char *text, int length) { (searchFlags & SCFIND_WHOLEWORD) != 0, (searchFlags & SCFIND_WORDSTART) != 0, (searchFlags & SCFIND_REGEXP) != 0, + (searchFlags & SCFIND_POSIX) != 0, &lengthFound); if (pos != -1) { targetStart = pos; diff --git a/src/RESearch.cxx b/src/RESearch.cxx index 77d897782..430a65e1f 100644 --- a/src/RESearch.cxx +++ b/src/RESearch.cxx @@ -30,6 +30,15 @@ * Modification history: * * $Log$ + * Revision 1.8 2003/03/04 10:53:59 nyamatongwe + * Patch from Jakub to optionally implement more POSIX compatible regular + * expressions. \(..\) changes to (..) + * Fixes problem where find previous would not find earlier matches on same + * line. + * + * Revision 1.8 2003/03/03 20:12:56 vrana + * Added posix syntax. + * * Revision 1.7 2002/09/28 00:33:28 nyamatongwe * Fixed problem with character ranges caused by expansion to 8 bits. * @@ -332,7 +341,7 @@ const char escapeValue(char ch) { return 0; } -const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { +const char *RESearch::Compile(const char *pat, int length, bool caseSensitive, bool posix) { char *mp=nfa; /* nfa pointer */ char *lp; /* saved pointer.. */ char *sp=nfa; /* another one.. */ @@ -467,25 +476,6 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { i++; switch(*++p) { - case '(': - if (tagc < MAXTAG) { - tagstk[++tagi] = tagc; - *mp++ = BOT; - *mp++ = static_cast<char>(tagc++); - } - else - return badpat("Too many \\(\\) pairs"); - break; - case ')': - if (*sp == BOT) - return badpat("Null pattern inside \\(\\)"); - if (tagi > 0) { - *mp++ = static_cast<char>(EOT); - *mp++ = static_cast<char>(tagstk[tagi--]); - } - else - return badpat("Unmatched \\)"); - break; case '<': *mp++ = BOW; break; @@ -524,13 +514,49 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { *mp++ = escapeValue(*p); break; default: - *mp++ = CHR; - *mp++ = *p; + if (!posix && *p == '(') { + if (tagc < MAXTAG) { + tagstk[++tagi] = tagc; + *mp++ = BOT; + *mp++ = static_cast<char>(tagc++); + } + else + return badpat("Too many \\(\\) pairs"); + } else if (!posix && *p == ')') { + if (*sp == BOT) + return badpat("Null pattern inside \\(\\)"); + if (tagi > 0) { + *mp++ = static_cast<char>(EOT); + *mp++ = static_cast<char>(tagstk[tagi--]); + } + else + return badpat("Unmatched \\)"); + } else { + *mp++ = CHR; + *mp++ = *p; + } } break; default : /* an ordinary char */ - if (caseSensitive) { + if (posix && *p == '(') { + if (tagc < MAXTAG) { + tagstk[++tagi] = tagc; + *mp++ = BOT; + *mp++ = static_cast<char>(tagc++); + } + else + return badpat("Too many () pairs"); + } else if (posix && *p == ')') { + if (*sp == BOT) + return badpat("Null pattern inside ()"); + if (tagi > 0) { + *mp++ = static_cast<char>(EOT); + *mp++ = static_cast<char>(tagstk[tagi--]); + } + else + return badpat("Unmatched )"); + } else if (caseSensitive) { *mp++ = CHR; *mp++ = *p; } else { @@ -545,7 +571,7 @@ const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) { sp = lp; } if (tagi > 0) - return badpat("Unmatched \\("); + return badpat((posix ? "Unmatched (" : "Unmatched \\(")); *mp = END; sta = OKP; return 0; diff --git a/src/RESearch.h b/src/RESearch.h index 9d0f20389..8ca9cd0b8 100644 --- a/src/RESearch.h +++ b/src/RESearch.h @@ -32,7 +32,7 @@ public: bool GrabMatches(CharacterIndexer &ci); void ChSet(char c); void ChSetWithCase(char c, bool caseSensitive); - const char *Compile(const char *pat, int length, bool caseSensitive); + const char *Compile(const char *pat, int length, bool caseSensitive, bool posix); int Execute(CharacterIndexer &ci, int lp, int endp); void ModifyWord(char *s); int Substitute(CharacterIndexer &ci, char *src, char *dst); |