diff options
| author | nyamatongwe <devnull@localhost> | 2001-04-29 13:32:10 +0000 | 
|---|---|---|
| committer | nyamatongwe <devnull@localhost> | 2001-04-29 13:32:10 +0000 | 
| commit | 09d42ffa21ce48f7ccd80c71674445bffe15cef1 (patch) | |
| tree | e5e81d31814afcd65759d81fd0ec7e375ca7603d | |
| parent | 33ce86f2a9e5389f7dd9922eb387936b61364259 (diff) | |
| download | scintilla-mirror-09d42ffa21ce48f7ccd80c71674445bffe15cef1.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.
| -rw-r--r-- | include/Scintilla.h | 5 | ||||
| -rw-r--r-- | include/Scintilla.iface | 19 | ||||
| -rw-r--r-- | src/Document.cxx | 44 | ||||
| -rw-r--r-- | src/Document.h | 2 | ||||
| -rw-r--r-- | src/Editor.cxx | 54 | ||||
| -rw-r--r-- | src/Editor.h | 4 | ||||
| -rw-r--r-- | src/RESearch.cxx | 120 | ||||
| -rw-r--r-- | src/RESearch.h | 6 | 
8 files changed, 178 insertions, 76 deletions
| diff --git a/include/Scintilla.h b/include/Scintilla.h index b1de42cee..a19d2a1b5 100644 --- a/include/Scintilla.h +++ b/include/Scintilla.h @@ -284,6 +284,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,  #define SCI_SETTARGETEND 2192  #define SCI_GETTARGETEND 2193  #define SCI_REPLACETARGET 2194 +#define SCI_REPLACETARGETCOUNTED 2195 +#define SCI_REPLACETARGETRECOUNTED 2196 +#define SCI_SEARCHINTARGET 2197 +#define SCI_SETSEARCHFLAGS 2198 +#define SCI_GETSEARCHFLAGS 2199  #define SCI_CALLTIPSHOW 2200  #define SCI_CALLTIPCANCEL 2201  #define SCI_CALLTIPACTIVE 2202 diff --git a/include/Scintilla.iface b/include/Scintilla.iface index 6764edfe2..4aaea15d4 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -736,6 +736,25 @@ get position GetTargetEnd=2193(,)  # caused by processing the \d patterns.  fun int ReplaceTarget=2194(bool replacePatterns, string text) +# Replace the target text with the argument text. +# Text is counted so it can contain nulls. +fun int ReplaceTargetCounted=2195(int length, string text) + +# Replace the target text with the argument text after \d processing. +# Text is counted so it can contain nulls. +fun int ReplaceTargetRECounted=2196(int length, string text) + +# Search for a counted string in the target and set the target to the found +# range. Text is counted so it can contain nulls. +# Returns length of range or -1 for failure in which case target is not moved. +fun int SearchInTarget=2197(int length, string text) + +# Set the search flags used by SearchInTarget +set void SetSearchFlags=2198(int flags,) + +# Get the search flags used by SearchInTarget +get int GetSearchFlags=2199(,) +  # Show a call tip containing a definition near position pos.  fun void CallTipShow=2200(position pos, string definition) 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..*/ | 
