aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Document.cxx
diff options
context:
space:
mode:
authornyamatongwe <unknown>2001-04-03 12:45:38 +0000
committernyamatongwe <unknown>2001-04-03 12:45:38 +0000
commit4a76af5c71efaf28a34e9399d985d74d23649ac2 (patch)
tree9af75d238ed93765984a8d5c3663c6b88ffac1f5 /src/Document.cxx
parent447b7052109f27609f2f89d031a76ad368b20946 (diff)
downloadscintilla-mirror-4a76af5c71efaf28a34e9399d985d74d23649ac2.tar.gz
Regular expression find support.
Diffstat (limited to 'src/Document.cxx')
-rw-r--r--src/Document.cxx155
1 files changed, 102 insertions, 53 deletions
diff --git a/src/Document.cxx b/src/Document.cxx
index 6be928cf7..babe25bcf 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -16,6 +16,7 @@
#include "SVector.h"
#include "CellBuffer.h"
#include "Document.h"
+#include "PosRegExp.h"
// This is ASCII specific but is safe with chars >= 0x80
inline bool isspacechar(unsigned char ch) {
@@ -742,70 +743,118 @@ bool Document::IsWordAt(int start, int end) {
return IsWordStartAt(start) && IsWordEndAt(end);
}
+char Document::DocCharAt(int pos, void *param) {
+ return reinterpret_cast<Document*>(param)->CharAt(pos);
+}
+
// Find text in document, supporting both forward and backward
// searches (just pass minPos > maxPos to do a backward search)
// 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 forward = minPos <= maxPos;
- int increment = forward ? 1 : -1;
-
- // Range endpoints should not be inside DBCS characters, but just in case, move them.
- int startPos = MovePositionOutsideChar(minPos, increment, false);
- int endPos = MovePositionOutsideChar(maxPos, increment, false);
-
- // Compute actual search ranges needed
- int lengthFind = strlen(s);
- int endSearch = endPos;
- if (startPos <= endPos) {
- endSearch = endPos - lengthFind + 1;
- }
- //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
- char firstChar = s[0];
- if (!caseSensitive)
- firstChar = static_cast<char>(toupper(firstChar));
- int pos = startPos;
- while (forward ? (pos < endSearch) : (pos >= endSearch)) {
- char ch = CharAt(pos);
- if (caseSensitive) {
- if (ch == firstChar) {
- bool found = true;
- for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
- ch = CharAt(pos + posMatch);
- if (ch != s[posMatch])
- found = false;
- }
- if (found) {
- if ((!word && !wordStart) ||
- word && IsWordAt(pos, pos + lengthFind) ||
- wordStart && IsWordStartAt(pos))
- return pos;
- }
- }
+ bool caseSensitive, bool word, bool wordStart, bool regExp,
+ int *length) {
+ if (regExp) {
+ char *pat = new char[strlen(s) + 4];
+ if (!pat)
+ return -1;
+
+ strcpy(pat, "/");
+ int startPos;
+ int endPos;
+
+ if (minPos <= maxPos) {
+ startPos = minPos;
+ endPos = maxPos;
} else {
- if (toupper(ch) == firstChar) {
- bool found = true;
- for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
- ch = CharAt(pos + posMatch);
- if (toupper(ch) != toupper(s[posMatch]))
- found = false;
+ startPos = maxPos;
+ endPos = minPos;
+ }
+
+ // Range endpoints should not be inside DBCS characters, but just in case, move them.
+ startPos = MovePositionOutsideChar(startPos, 1, false);
+ endPos = MovePositionOutsideChar(endPos, 1, false);
+
+ strcat(pat, s);
+ strcat(pat, "/");
+ PosRegExp re;
+ if (!caseSensitive)
+ strcat(pat, "i");
+ if (!re.SetExpr(pat)) {
+ delete []pat;
+ return -1;
+ }
+ re.param = this;
+ re.CharAt = DocCharAt;
+ SMatches matches;
+ if (!re.Parse(startPos, 0, endPos, &matches)) {
+ delete []pat;
+ return -1;
+ }
+ *length = matches.e[0] - matches.s[0];
+ delete []pat;
+ return matches.s[0];
+ } else {
+
+ bool forward = minPos <= maxPos;
+ int increment = forward ? 1 : -1;
+
+ // Range endpoints should not be inside DBCS characters, but just in case, move them.
+ int startPos = MovePositionOutsideChar(minPos, increment, false);
+ int endPos = MovePositionOutsideChar(maxPos, increment, false);
+
+ // Compute actual search ranges needed
+ int lengthFind = strlen(s);
+ int endSearch = endPos;
+ if (startPos <= endPos) {
+ endSearch = endPos - lengthFind + 1;
+ }
+ //Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
+ char firstChar = s[0];
+ if (!caseSensitive)
+ firstChar = static_cast<char>(toupper(firstChar));
+ int pos = startPos;
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ char ch = CharAt(pos);
+ if (caseSensitive) {
+ if (ch == firstChar) {
+ bool found = true;
+ for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
+ ch = CharAt(pos + posMatch);
+ if (ch != s[posMatch])
+ found = false;
+ }
+ if (found) {
+ if ((!word && !wordStart) ||
+ word && IsWordAt(pos, pos + lengthFind) ||
+ wordStart && IsWordStartAt(pos))
+ return pos;
+ }
}
- if (found) {
- if ((!word && !wordStart) ||
- word && IsWordAt(pos, pos + lengthFind) ||
- wordStart && IsWordStartAt(pos))
- return pos;
+ } else {
+ if (toupper(ch) == firstChar) {
+ bool found = true;
+ for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
+ ch = CharAt(pos + posMatch);
+ if (toupper(ch) != toupper(s[posMatch]))
+ found = false;
+ }
+ if (found) {
+ if ((!word && !wordStart) ||
+ word && IsWordAt(pos, pos + lengthFind) ||
+ wordStart && IsWordStartAt(pos))
+ return pos;
+ }
}
}
- }
- pos += increment;
- if (dbcsCodePage) {
- // Ensure trying to match from start of character
- pos = MovePositionOutsideChar(pos, increment, false);
+ pos += increment;
+ if (dbcsCodePage) {
+ // Ensure trying to match from start of character
+ pos = MovePositionOutsideChar(pos, increment, false);
+ }
}
}
//Platform::DebugPrintf("Not found\n");
- return - 1;
+ return -1;
}
int Document::LinesTotal() {