aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authornyamatongwe <unknown>2001-04-29 13:32:10 +0000
committernyamatongwe <unknown>2001-04-29 13:32:10 +0000
commit1bd2d31b3ce8714ddeba3d9825a8a605e55751cf (patch)
treee5e81d31814afcd65759d81fd0ec7e375ca7603d /src
parent47c3e67c26e19f237bab42d3a98019add82bb4b5 (diff)
downloadscintilla-mirror-1bd2d31b3ce8714ddeba3d9825a8a605e55751cf.tar.gz
Addition of new target methods - versions of ReplaceTarget that take counted
strings to allow for nulls, SearchInTarget and Get/SetSearchFlags to use a series of calls rather than a structure. Handling of \000 in search and replace. Handling of /escapes within character ranges of regular expressions. Some handling of bare ^ and $ regular expressions.
Diffstat (limited to 'src')
-rw-r--r--src/Document.cxx44
-rw-r--r--src/Document.h2
-rw-r--r--src/Editor.cxx54
-rw-r--r--src/Editor.h4
-rw-r--r--src/RESearch.cxx120
-rw-r--r--src/RESearch.h6
6 files changed, 154 insertions, 76 deletions
diff --git a/src/Document.cxx b/src/Document.cxx
index 70ad061a5..ef9779016 100644
--- a/src/Document.cxx
+++ b/src/Document.cxx
@@ -826,7 +826,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, caseSensitive);
+ const char *errmsg = pre->Compile(s, *length, caseSensitive);
if (errmsg) {
return -1;
}
@@ -841,6 +841,18 @@ long Document::FindText(int minPos, int maxPos, const char *s,
char searchEnd = '\0';
if (*s)
searchEnd = s[strlen(s) - 1];
+ if (*length == 1) {
+ // These produce empty selections so nudge them on if needed
+ if (s[0] == '^') {
+ if (startPos == LineStart(lineRangeStart))
+ startPos++;
+ } else if (s[0] == '$') {
+ if ((startPos == LineEnd(lineRangeStart)) && (lineRangeStart < lineRangeEnd))
+ startPos = LineStart(lineRangeStart+1);
+ }
+ lineRangeStart = LineFromPosition(startPos);
+ lineRangeEnd = LineFromPosition(endPos);
+ }
for (int line = lineRangeStart; line <= lineRangeEnd; line++) {
int startOfLine = LineStart(line);
int endOfLine = LineEnd(line);
@@ -855,7 +867,7 @@ long Document::FindText(int minPos, int maxPos, const char *s,
endOfLine = endPos;
}
DocumentIndexer di(this, endOfLine);
- int success = pre->Execute(di, startOfLine);
+ int success = pre->Execute(di, startOfLine, endOfLine);
if (success) {
pos = pre->bopat[0];
lenRet = pre->eopat[0] - pre->bopat[0];
@@ -875,7 +887,9 @@ long Document::FindText(int minPos, int maxPos, const char *s,
int endPos = MovePositionOutsideChar(maxPos, increment, false);
// Compute actual search ranges needed
- int lengthFind = strlen(s);
+ int lengthFind = *length;
+ if (lengthFind == -1)
+ lengthFind = strlen(s);
int endSearch = endPos;
if (startPos <= endPos) {
endSearch = endPos - lengthFind + 1;
@@ -929,7 +943,7 @@ long Document::FindText(int minPos, int maxPos, const char *s,
return -1;
}
-const char *Document::SubstituteByPosition(const char *text) {
+const char *Document::SubstituteByPosition(const char *text, int *length) {
if (!pre)
return 0;
delete []substituted;
@@ -938,11 +952,11 @@ const char *Document::SubstituteByPosition(const char *text) {
if (!pre->GrabMatches(di))
return 0;
unsigned int lenResult = 0;
- for (const char *t = text; *t; t++) {
- if ((*t == '\\') && (*(t + 1) >= '1' && *(t + 1) <= '9')) {
- unsigned int patNum = *(t + 1) - '0';
+ for (int i=0; i<*length; i++) {
+ if ((text[i] == '\\') && (text[i+1] >= '1' && text[i+1] <= '9')) {
+ unsigned int patNum = text[i+1] - '0';
lenResult += pre->eopat[patNum] - pre->bopat[patNum];
- t++;
+ i++;
} else {
lenResult++;
}
@@ -951,18 +965,20 @@ const char *Document::SubstituteByPosition(const char *text) {
if (!substituted)
return 0;
char *o = substituted;
- for (const char *s = text; *s; s++) {
- if ((*s == '\\') && (*(s + 1) >= '1' && *(s + 1) <= '9')) {
- unsigned int patNum = *(s + 1) - '0';
+ for (int j=0; j<*length; j++) {
+ if ((text[j] == '\\') && (text[j+1] >= '1' && text[j+1] <= '9')) {
+ unsigned int patNum = text[j+1] - '0';
unsigned int len = pre->eopat[patNum] - pre->bopat[patNum];
- strcpy(o, pre->pat[patNum]);
+ if (pre->pat[patNum]) // Will be null if try for a match that did not occur
+ memcpy(o, pre->pat[patNum], len);
o += len;
- s++;
+ j++;
} else {
- *o++ = *s;
+ *o++ = text[j];
}
}
*o = '\0';
+ *length = lenResult;
return substituted;
}
diff --git a/src/Document.h b/src/Document.h
index bfc1a6e57..aac0a971b 100644
--- a/src/Document.h
+++ b/src/Document.h
@@ -180,7 +180,7 @@ public:
long FindText(int minPos, int maxPos, const char *s,
bool caseSensitive, bool word, bool wordStart, bool regExp, int *length);
long FindText(int iMessage, unsigned long wParam, long lParam);
- const char *SubstituteByPosition(const char *text);
+ const char *SubstituteByPosition(const char *text, int *length);
int LinesTotal();
void ChangeCase(Range r, bool makeUpperCase);
diff --git a/src/Editor.cxx b/src/Editor.cxx
index e44fbc9f9..01eb02241 100644
--- a/src/Editor.cxx
+++ b/src/Editor.cxx
@@ -94,7 +94,8 @@ Editor::Editor() {
targetStart = 0;
targetEnd = 0;
-
+ searchFlags = 0;
+
topLine = 0;
posTopLine = 0;
@@ -2541,6 +2542,25 @@ long Editor::SearchText(
return pos;
}
+/**
+ * Search for text in the target range of the document.
+ * @return The position of the found text, -1 if not found.
+ */
+long Editor::SearchInTarget(const char *text, int length) {
+ int lengthFound = length;
+ int pos = pdoc->FindText(targetStart, targetEnd, text,
+ searchFlags & SCFIND_MATCHCASE,
+ searchFlags & SCFIND_WHOLEWORD,
+ searchFlags & SCFIND_WORDSTART,
+ searchFlags & SCFIND_REGEXP,
+ &lengthFound);
+ if (pos != -1) {
+ targetStart = pos;
+ targetEnd = pos + lengthFound;
+ }
+ return pos;
+}
+
void Editor::GoToLine(int lineNo) {
if (lineNo > pdoc->LinesTotal())
lineNo = pdoc->LinesTotal();
@@ -3267,21 +3287,22 @@ void Editor::EnsureLineVisible(int lineDoc) {
}
}
-int Editor::ReplaceTarget(bool replacePatterns, const char *text) {
+int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
pdoc->BeginUndoAction();
+ if (length == -1)
+ length = strlen(text);
if (replacePatterns) {
- text = pdoc->SubstituteByPosition(text);
+ text = pdoc->SubstituteByPosition(text, &length);
if (!text)
return 0;
}
if (targetStart != targetEnd)
pdoc->DeleteChars(targetStart, targetEnd - targetStart);
targetEnd = targetStart;
- unsigned int len = strlen(text);
- pdoc->InsertString(targetStart, text);
- targetEnd = targetStart + len;
+ pdoc->InsertString(targetStart, text, length);
+ targetEnd = targetStart + length;
pdoc->EndUndoAction();
- return len;
+ return length;
}
static bool ValidMargin(unsigned long wParam) {
@@ -3619,6 +3640,25 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_REPLACETARGET:
PLATFORM_ASSERT(lParam);
return ReplaceTarget(wParam, reinterpret_cast<char *>(lParam));
+
+ case SCI_REPLACETARGETCOUNTED:
+ PLATFORM_ASSERT(lParam);
+ return ReplaceTarget(false, reinterpret_cast<char *>(lParam), wParam);
+
+ case SCI_REPLACETARGETRECOUNTED:
+ PLATFORM_ASSERT(lParam);
+ return ReplaceTarget(true, reinterpret_cast<char *>(lParam), wParam);
+
+ case SCI_SEARCHINTARGET:
+ PLATFORM_ASSERT(lParam);
+ return SearchInTarget(reinterpret_cast<char *>(lParam), wParam);
+
+ case SCI_SETSEARCHFLAGS:
+ searchFlags = wParam;
+ break;
+
+ case SCI_GETSEARCHFLAGS:
+ return searchFlags;
case EM_LINESCROLL:
case SCI_LINESCROLL:
diff --git a/src/Editor.h b/src/Editor.h
index c7c7b114e..7ed4868fe 100644
--- a/src/Editor.h
+++ b/src/Editor.h
@@ -118,6 +118,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int anchor;
int targetStart;
int targetEnd;
+ int searchFlags;
int topLine;
int posTopLine;
@@ -285,6 +286,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
long FindText(unsigned int iMessage, unsigned long wParam, long lParam);
void SearchAnchor();
long SearchText(unsigned int iMessage, unsigned long wParam, long lParam);
+ long SearchInTarget(const char *text, int length);
void GoToLine(int lineNo);
char *CopyRange(int start, int end);
@@ -320,7 +322,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void Expand(int &line, bool doExpand);
void ToggleContraction(int line);
void EnsureLineVisible(int lineDoc);
- int ReplaceTarget(bool replacePatterns, const char *text);
+ int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
virtual sptr_t DefWndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) = 0;
diff --git a/src/RESearch.cxx b/src/RESearch.cxx
index 82f08b6e5..e0f821d31 100644
--- a/src/RESearch.cxx
+++ b/src/RESearch.cxx
@@ -30,6 +30,14 @@
* Modification history:
*
* $Log$
+ * Revision 1.6 2001/04/29 13:32:10 nyamatongwe
+ * Addition of new target methods - versions of ReplaceTarget that take counted
+ * strings to allow for nulls, SearchInTarget and Get/SetSearchFlags to use a
+ * series of calls rather than a structure.
+ * Handling of \000 in search and replace.
+ * Handling of /escapes within character ranges of regular expressions.
+ * Some handling of bare ^ and $ regular expressions.
+ *
* Revision 1.5 2001/04/20 07:36:09 nyamatongwe
* Removed DEBUG code that failed to compile on GTK+.
*
@@ -214,8 +222,6 @@
#include "RESearch.h"
-#define EXTEND
-
#define OKP 1
#define NOP 0
@@ -310,8 +316,20 @@ void RESearch::ChSetWithCase(char c, bool caseSensitive) {
}
}
-const char *RESearch::Compile(const char *pat, bool caseSensitive) {
- const char *p; /* pattern pointer */
+const char escapeValue(char ch) {
+ switch (ch) {
+ case 'a': return '\a';
+ case 'b': return '\b';
+ case 'f': return '\f';
+ case 'n': return '\n';
+ case 'r': return '\r';
+ case 't': return '\t';
+ case 'v': return '\v';
+ }
+ return 0;
+}
+
+const char *RESearch::Compile(const char *pat, int length, bool caseSensitive) {
char *mp=nfa; /* nfa pointer */
char *lp; /* saved pointer.. */
char *sp=nfa; /* another one.. */
@@ -323,14 +341,15 @@ const char *RESearch::Compile(const char *pat, bool caseSensitive) {
char mask; /* xor mask -CCL/NCL */
int c1, c2;
- if (!pat || !*pat)
+ if (!pat || !length)
if (sta)
return 0;
else
return badpat("No previous regular expression");
sta = NOP;
- for (p = pat; *p; p++) {
+ const char *p=pat; /* pattern pointer */
+ for (int i=0; i<length; i++, p++) {
lp = mp;
switch(*p) {
@@ -359,34 +378,46 @@ const char *RESearch::Compile(const char *pat, bool caseSensitive) {
case '[': /* match char class..*/
*mp++ = CCL;
+ i++;
if (*++p == '^') {
mask = '\377';
+ i++;
p++;
- }
- else
+ } else
mask = 0;
- if (*p == '-') /* real dash */
+ if (*p == '-') { /* real dash */
+ i++;
ChSet(*p++);
- if (*p == ']') /* real brac */
+ }
+ if (*p == ']') { /* real brace */
+ i++;
ChSet(*p++);
+ }
while (*p && *p != ']') {
if (*p == '-' && *(p+1) && *(p+1) != ']') {
+ i++;
p++;
c1 = *(p-2) + 1;
+ i++;
c2 = *p++;
while (c1 <= c2) {
ChSetWithCase(static_cast<char>(c1++), caseSensitive);
}
- }
-#ifdef EXTEND
- else if (*p == '\\' && *(p+1)) {
+ } else if (*p == '\\' && *(p+1)) {
+ i++;
p++;
+ char escape = escapeValue(*p);
+ if (escape)
+ ChSetWithCase(escape, caseSensitive);
+ else
+ ChSetWithCase(*p, caseSensitive);
+ i++;
+ p++;
+ } else {
+ i++;
ChSetWithCase(*p++, caseSensitive);
}
-#endif
- else
- ChSetWithCase(*p++, caseSensitive);
}
if (!*p)
return badpat("Missing ]");
@@ -430,6 +461,7 @@ const char *RESearch::Compile(const char *pat, bool caseSensitive) {
break;
case '\\': /* tags, backrefs .. */
+ i++;
switch(*++p) {
case '(':
@@ -478,36 +510,16 @@ const char *RESearch::Compile(const char *pat, bool caseSensitive) {
else
return badpat("Undetermined reference");
break;
-#ifdef EXTEND
case 'a':
- *mp++ = CHR;
- *mp++ = '\a';
- break;
case 'b':
- *mp++ = CHR;
- *mp++ = '\b';
- break;
case 'n':
- *mp++ = CHR;
- *mp++ = '\n';
- break;
case 'f':
- *mp++ = CHR;
- *mp++ = '\f';
- break;
case 'r':
- *mp++ = CHR;
- *mp++ = '\r';
- break;
case 't':
- *mp++ = CHR;
- *mp++ = '\t';
- break;
case 'v':
*mp++ = CHR;
- *mp++ = '\v';
+ *mp++ = escapeValue(*p);
break;
-#endif
default:
*mp++ = CHR;
*mp++ = *p;
@@ -558,7 +570,7 @@ const char *RESearch::Compile(const char *pat, bool caseSensitive) {
*
*/
-int RESearch::Execute(CharacterIndexer &ci, int lp) {
+int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
char c;
int ep = NOTFOUND;
char *ap = nfa;
@@ -571,17 +583,25 @@ int RESearch::Execute(CharacterIndexer &ci, int lp) {
switch(*ap) {
case BOL: /* anchored: match from BOL only */
- ep = PMatch(ci, lp, ap);
+ ep = PMatch(ci, lp, endp, ap);
break;
+ case EOL: /* just searching for end of line normal path doesn't work */
+ if (*(ap+1) == END) {
+ lp = endp;
+ ep = lp;
+ break;
+ } else {
+ return 0;
+ }
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
- while (ci.CharAt(lp) && ci.CharAt(lp) != c)
+ while ((lp < endp) && (ci.CharAt(lp) != c))
lp++;
- if (!ci.CharAt(lp)) /* if EOS, fail, else fall thru. */
+ if (lp >= endp) /* if EOS, fail, else fall thru. */
return 0;
default: /* regular matching all the way. */
- while (ci.CharAt(lp)) {
- ep = PMatch(ci, lp, ap);
+ while (lp < endp) {
+ ep = PMatch(ci, lp, endp, ap);
if (ep != NOTFOUND)
break;
lp++;
@@ -667,7 +687,7 @@ static char chrtyp[MAXCHR] = {
#define CHRSKIP 3 /* [CLO] CHR chr END ... */
#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */
-int RESearch::PMatch(CharacterIndexer &ci, int lp, char *ap) {
+int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
int op, c, n;
int e; /* extra pointer for CLO */
int bp; /* beginning of subpat.. */
@@ -682,7 +702,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, char *ap) {
return NOTFOUND;
break;
case ANY:
- if (!ci.CharAt(lp++))
+ if (lp++ >= endp)
return NOTFOUND;
break;
case CCL:
@@ -696,7 +716,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, char *ap) {
return NOTFOUND;
break;
case EOL:
- if (ci.CharAt(lp))
+ if (lp < endp)
return NOTFOUND;
break;
case BOT:
@@ -726,18 +746,18 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, char *ap) {
switch(*ap) {
case ANY:
- while (ci.CharAt(lp))
+ while (lp < endp)
lp++;
n = ANYSKIP;
break;
case CHR:
c = *(ap+1);
- while (ci.CharAt(lp) && c == ci.CharAt(lp))
+ while ((lp < endp) && (c == ci.CharAt(lp)))
lp++;
n = CHRSKIP;
break;
case CCL:
- while (((c = ci.CharAt(lp)) != 0) && isinset(ap+1,c))
+ while ((lp < endp) && isinset(ap+1,ci.CharAt(lp)))
lp++;
n = CCLSKIP;
break;
@@ -750,7 +770,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, char *ap) {
ap += n;
while (lp >= are) {
- if ((e = PMatch(ci, lp, ap)) != NOTFOUND)
+ if ((e = PMatch(ci, lp, endp, ap)) != NOTFOUND)
return e;
--lp;
}
diff --git a/src/RESearch.h b/src/RESearch.h
index 14a5471fd..28238bfb7 100644
--- a/src/RESearch.h
+++ b/src/RESearch.h
@@ -32,8 +32,8 @@ public:
bool GrabMatches(CharacterIndexer &ci);
void ChSet(char c);
void ChSetWithCase(char c, bool caseSensitive);
- const char *Compile(const char *pat, bool caseSensitive);
- int Execute(CharacterIndexer &ci, int lp);
+ const char *Compile(const char *pat, int length, bool caseSensitive);
+ int Execute(CharacterIndexer &ci, int lp, int endp);
void ModifyWord(char *s);
int Substitute(CharacterIndexer &ci, char *src, char *dst);
@@ -46,7 +46,7 @@ public:
char *pat[MAXTAG];
private:
- int PMatch(CharacterIndexer &ci, int lp, char *ap);
+ int PMatch(CharacterIndexer &ci, int lp, int endp, char *ap);
int bol;
int tagstk[MAXTAG]; /* subpat tag stack..*/