diff options
author | nyamatongwe <devnull@localhost> | 2001-04-06 12:24:21 +0000 |
---|---|---|
committer | nyamatongwe <devnull@localhost> | 2001-04-06 12:24:21 +0000 |
commit | 031fdca93e03464d541a3255a92a7b5603b14a50 (patch) | |
tree | d12c6a496b4c11b3d8f3f3a30689ef9ee1fbf7a0 | |
parent | 529ea750b146c23bd1f8c0ec0b3bbeb64689a736 (diff) | |
download | scintilla-mirror-031fdca93e03464d541a3255a92a7b5603b14a50.tar.gz |
Made regular expression searching work on a line by line basis, made ^ and
$ work, made [set] work, and added a case insensitive option.
-rw-r--r-- | src/Document.cxx | 40 | ||||
-rw-r--r-- | src/RESearch.cxx | 47 | ||||
-rw-r--r-- | src/RESearch.h | 3 |
3 files changed, 67 insertions, 23 deletions
diff --git a/src/Document.cxx b/src/Document.cxx index 8adf2daf2..4a915314d 100644 --- a/src/Document.cxx +++ b/src/Document.cxx @@ -791,15 +791,12 @@ long Document::FindText(int minPos, int maxPos, const char *s, bool caseSensitive, bool word, bool wordStart, bool regExp, int *length) { if (regExp) { + if (!pre) pre = new RESearch(); if (!pre) return -1; - char *pat = new char[strlen(s) + 1]; - if (!pat) - return -1; - pat[0] = '\0'; int startPos; int endPos; @@ -815,25 +812,42 @@ long Document::FindText(int minPos, int maxPos, const char *s, startPos = MovePositionOutsideChar(startPos, 1, false); endPos = MovePositionOutsideChar(endPos, 1, false); - DocumentIndexer di(this, endPos); - strcat(pat, s); - const char *errmsg = pre->Compile(pat); + const char *errmsg = pre->Compile(s, caseSensitive); if (errmsg) { - delete []pat; return -1; } // Find a variable in a property file: \$(\([A-Za-z0-9_.]+\)) // Replace first '.' with '-' in each property file variable reference: // Search: \$(\([A-Za-z0-9_-]+\)\.\([A-Za-z0-9_.]+\)) // Replace: $(\1-\2) - int success = pre->Execute(di, startPos); + int lineRangeStart = LineFromPosition(startPos); + int lineRangeEnd = LineFromPosition(endPos); int pos = -1; int lenRet = 0; - if (success) { - pos = pre->bopat[0]; - lenRet = pre->eopat[0] - pre->bopat[0]; + char searchEnd = '\0'; + if (*s) + searchEnd = s[strlen(s)-1]; + for (int line=lineRangeStart; line<=lineRangeEnd; line++) { + int startOfLine = LineStart(line); + int endOfLine = LineEnd(line); + 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; + } + DocumentIndexer di(this, endOfLine); + int success = pre->Execute(di, startOfLine); + if (success) { + pos = pre->bopat[0]; + lenRet = pre->eopat[0] - pre->bopat[0]; + break; + } } - delete []pat; *length = lenRet; return pos; diff --git a/src/RESearch.cxx b/src/RESearch.cxx index fbc116363..473f2bacc 100644 --- a/src/RESearch.cxx +++ b/src/RESearch.cxx @@ -29,6 +29,10 @@ * Modification history: * * $Log$ + * Revision 1.3 2001/04/06 12:24:21 nyamatongwe + * Made regular expression searching work on a line by line basis, made ^ and + * $ work, made [set] work, and added a case insensitive option. + * * Revision 1.2 2001/04/05 01:58:04 nyamatongwe * Replace target functionality to make find and replace operations faster * by diminishing screen updates and allow for \d patterns in the replacement @@ -283,8 +287,24 @@ void RESearch::ChSet(char c) { bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND]; } -const char *RESearch::Compile(char *pat) { - char *p; /* pattern pointer */ +void RESearch::ChSetWithCase(char c, bool caseSensitive) { + if (caseSensitive) { + ChSet(c); + } else { + if ((c >= 'a') && (c <= 'z')) { + ChSet(c); + ChSet(static_cast<char>(c - 'a' + 'A')); + } else if ((c >= 'A') && (c <= 'Z')) { + ChSet(c); + ChSet(static_cast<char>(c - 'A' + 'a')); + } else { + ChSet(c); + } + } +} + +const char *RESearch::Compile(const char *pat, bool caseSensitive) { + const char *p; /* pattern pointer */ char *mp=nfa; /* nfa pointer */ char *lp; /* saved pointer.. */ char *sp=nfa; /* another one.. */ @@ -348,17 +368,18 @@ const char *RESearch::Compile(char *pat) { p++; c1 = *(p-2) + 1; c2 = *p++; - while (c1 <= c2) - ChSet(static_cast<char>(c1++)); + while (c1 <= c2) { + ChSetWithCase(static_cast<char>(c1++), caseSensitive); + } } #ifdef EXTEND else if (*p == '\\' && *(p+1)) { p++; - ChSet(*p++); + ChSetWithCase(*p++, caseSensitive); } #endif else - ChSet(*p++); + ChSetWithCase(*p++, caseSensitive); } if (!*p) return badpat("Missing ]"); @@ -487,8 +508,16 @@ const char *RESearch::Compile(char *pat) { break; default : /* an ordinary char */ - *mp++ = CHR; - *mp++ = *p; + if (caseSensitive) { + *mp++ = CHR; + *mp++ = *p; + } else { + *mp++ = CCL; + mask = 0; + ChSetWithCase(*p, false); + for (n = 0; n < BITBLK; bittab[n++] = (char) 0) + *mp++ = static_cast<char>(mask ^ bittab[n]); + } break; } sp = lp; @@ -524,7 +553,7 @@ const char *RESearch::Compile(char *pat) { int RESearch::Execute(CharacterIndexer &ci, int lp) { char c; - int ep = 0; + int ep = NOTFOUND; char *ap = nfa; bol = lp; diff --git a/src/RESearch.h b/src/RESearch.h index 62a78f48e..14a5471fd 100644 --- a/src/RESearch.h +++ b/src/RESearch.h @@ -31,7 +31,8 @@ public: void Clear(); bool GrabMatches(CharacterIndexer &ci); void ChSet(char c); - const char *Compile(char *pat); + void ChSetWithCase(char c, bool caseSensitive); + const char *Compile(const char *pat, bool caseSensitive); int Execute(CharacterIndexer &ci, int lp); void ModifyWord(char *s); int Substitute(CharacterIndexer &ci, char *src, char *dst); |