diff options
Diffstat (limited to 'lexers')
| -rw-r--r-- | lexers/LexBatch.cxx | 835 | 
1 files changed, 454 insertions, 381 deletions
| diff --git a/lexers/LexBatch.cxx b/lexers/LexBatch.cxx index db7e37688..ee71c528f 100644 --- a/lexers/LexBatch.cxx +++ b/lexers/LexBatch.cxx @@ -41,7 +41,8 @@ static inline bool AtEOL(Accessor &styler, Sci_PositionU i) {  // Tests for BATCH Operators  static bool IsBOperator(char ch) {  	return (ch == '=') || (ch == '+') || (ch == '>') || (ch == '<') || -		(ch == '|') || (ch == '?') || (ch == '*'); +		(ch == '|') || (ch == '?') || (ch == '*')|| +		(ch == '&') || (ch == '(') || (ch == ')');  }  // Tests for BATCH Separators @@ -50,218 +51,198 @@ static bool IsBSeparator(char ch) {  		(ch == '\"') || (ch == '\'') || (ch == '/');  } -static void ColouriseBatchLine( -    char *lineBuffer, -    Sci_PositionU lengthLine, -    Sci_PositionU startLine, -    Sci_PositionU endPos, +// Tests for escape character +static bool IsEscaped(char* wordStr, Sci_PositionU pos) { +	bool isQoted=false; +	while (pos>0){ +		pos--; +		if (wordStr[pos]=='^') +			isQoted=!isQoted; +		else +			break; +	} +	return isQoted; +} + +// Tests for quote character +static bool textQuoted(char *lineBuffer, Sci_PositionU endPos) { +	char strBuffer[1024]; +	strncpy(strBuffer, lineBuffer, endPos); +	strBuffer[endPos] = '\0'; +	char *pQuote; +	pQuote = strchr(strBuffer, '"'); +	bool CurrentStatus = false; +	while (pQuote != NULL) +	{ +		if (!IsEscaped(strBuffer, pQuote - strBuffer)) { +			CurrentStatus = !CurrentStatus; +		} +		pQuote = strchr(pQuote + 1, '"'); +	} +	return CurrentStatus; +} + +static void ColouriseBatchDoc( +    Sci_PositionU startPos, +    Sci_Position length, +    int /*initStyle*/,      WordList *keywordlists[],      Accessor &styler) { +	// Always backtracks to the start of a line that is not a continuation +	// of the previous line +	if (startPos > 0) { +		Sci_Position ln = styler.GetLine(startPos); // Current line number +		while (startPos > 0) { +			ln--; +			if ((styler.SafeGetCharAt(startPos-3) == '^' && styler.SafeGetCharAt(startPos-2) == '\r' && styler.SafeGetCharAt(startPos-1) == '\n') +			|| styler.SafeGetCharAt(startPos-2) == '^') {	// handle '^' line continuation +				// When the line continuation is found, +				// set the Start Position to the Start of the previous line +				length+=startPos-styler.LineStart(ln); +				startPos=styler.LineStart(ln); +			} +			else +				break; +		} +	} -	Sci_PositionU offset = 0;	// Line Buffer Offset -	Sci_PositionU cmdLoc;		// External Command / Program Location -	char wordBuffer[81];		// Word Buffer - large to catch long paths -	Sci_PositionU wbl;		// Word Buffer Length -	Sci_PositionU wbo;		// Word Buffer Offset - also Special Keyword Buffer Length -	WordList &keywords = *keywordlists[0];      // Internal Commands -	WordList &keywords2 = *keywordlists[1];     // External Commands (optional) +	char lineBuffer[1024]; -	// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords -	//   Toggling Regular Keyword Checking off improves readability -	// Other Regular Keywords and External Commands / Programs might also benefit from toggling -	//   Need a more robust algorithm to properly toggle Regular Keyword Checking +	styler.StartAt(startPos); +	styler.StartSegment(startPos); +	Sci_PositionU linePos = 0; +	Sci_PositionU startLine = startPos;  	bool continueProcessing = true;	// Used to toggle Regular Keyword Checking -	// Special Keywords are those that allow certain characters without whitespace after the command -	// Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= -	// Special Keyword Buffer used to determine if the first n characters is a Keyword -	char sKeywordBuffer[10];	// Special Keyword Buffer -	bool sKeywordFound;		// Exit Special Keyword for-loop if found - -	// Skip initial spaces -	while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { -		offset++; -	} -	// Colorize Default Text -	styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); -	// Set External Command / Program Location -	cmdLoc = offset; +	bool isNotAssigned=false; // Used to flag Assignment in Set operation -	// Check for Fake Label (Comment) or Real Label - return if found -	if (lineBuffer[offset] == ':') { -		if (lineBuffer[offset + 1] == ':') { -			// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm -			styler.ColourTo(endPos, SCE_BAT_COMMENT); -		} else { -			// Colorize Real Label -			styler.ColourTo(endPos, SCE_BAT_LABEL); -		} -		return; -	// Check for Drive Change (Drive Change is internal command) - return if found -	} else if ((IsAlphabetic(lineBuffer[offset])) && -		(lineBuffer[offset + 1] == ':') && -		((isspacechar(lineBuffer[offset + 2])) || -		(((lineBuffer[offset + 2] == '\\')) && -		(isspacechar(lineBuffer[offset + 3]))))) { -		// Colorize Regular Keyword -		styler.ColourTo(endPos, SCE_BAT_WORD); -		return; -	} +	for (Sci_PositionU i = startPos; i < startPos + length; i++) { +		lineBuffer[linePos++] = styler[i]; +		if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1) || (i==startPos + length-1)) { +			// End of line (or of line buffer) (or End of Last Line) met, colourise it +			lineBuffer[linePos] = '\0'; +			Sci_PositionU lengthLine=linePos; +			Sci_PositionU endPos=i; +			Sci_PositionU offset = 0;	// Line Buffer Offset +			Sci_PositionU cmdLoc;		// External Command / Program Location +			char wordBuffer[81];		// Word Buffer - large to catch long paths +			Sci_PositionU wbl;		// Word Buffer Length +			Sci_PositionU wbo;		// Word Buffer Offset - also Special Keyword Buffer Length +			WordList &keywords = *keywordlists[0];      // Internal Commands +			WordList &keywords2 = *keywordlists[1];     // External Commands (optional) -	// Check for Hide Command (@ECHO OFF/ON) -	if (lineBuffer[offset] == '@') { -		styler.ColourTo(startLine + offset, SCE_BAT_HIDE); -		offset++; -	} -	// Skip next spaces -	while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { -		offset++; -	} +			// CHOICE, ECHO, GOTO, PROMPT and SET have Default Text that may contain Regular Keywords +			//   Toggling Regular Keyword Checking off improves readability +			// Other Regular Keywords and External Commands / Programs might also benefit from toggling +			//   Need a more robust algorithm to properly toggle Regular Keyword Checking +			bool stopLineProcessing=false;  // Used to stop line processing if Comment or Drive Change found +			// Special Keywords are those that allow certain characters without whitespace after the command +			// Examples are: cd. cd\ md. rd. dir| dir> echo: echo. path= +			// Special Keyword Buffer used to determine if the first n characters is a Keyword +			char sKeywordBuffer[10];	// Special Keyword Buffer +			bool sKeywordFound;		// Exit Special Keyword for-loop if found -	// Read remainder of line word-at-a-time or remainder-of-word-at-a-time -	while (offset < lengthLine) { -		if (offset > startLine) { +			// Skip initial spaces +			while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { +				offset++; +			}  			// Colorize Default Text  			styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); -		} -		// Copy word from Line Buffer into Word Buffer -		wbl = 0; -		for (; offset < lengthLine && wbl < 80 && -		        !isspacechar(lineBuffer[offset]); wbl++, offset++) { -			wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset])); -		} -		wordBuffer[wbl] = '\0'; -		wbo = 0; +			// Set External Command / Program Location +			cmdLoc = offset; -		// Check for Comment - return if found -		if (CompareCaseInsensitive(wordBuffer, "rem") == 0) { -			styler.ColourTo(endPos, SCE_BAT_COMMENT); -			return; -		} -		// Check for Separator -		if (IsBSeparator(wordBuffer[0])) { -			// Check for External Command / Program -			if ((cmdLoc == offset - wbl) && -				((wordBuffer[0] == ':') || -				(wordBuffer[0] == '\\') || -				(wordBuffer[0] == '.'))) { -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 1); -				// Colorize External Command / Program -				if (!keywords2) { -					styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); -				} else if (keywords2.InList(wordBuffer)) { -					styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); +			// Check for Fake Label (Comment) or Real Label - return if found +			if (lineBuffer[offset] == ':') { +				if (lineBuffer[offset + 1] == ':') { +					// Colorize Fake Label (Comment) - :: is similar to REM, see http://content.techweb.com/winmag/columns/explorer/2000/21.htm +					styler.ColourTo(endPos, SCE_BAT_COMMENT);  				} else { -					styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); +					// Colorize Real Label +					styler.ColourTo(endPos, SCE_BAT_LABEL);  				} -				// Reset External Command / Program Location -				cmdLoc = offset; -			} else { -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 1); -				// Colorize Default Text -				styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); +				stopLineProcessing=true; +			// Check for Drive Change (Drive Change is internal command) - return if found +			} else if ((IsAlphabetic(lineBuffer[offset])) && +				(lineBuffer[offset + 1] == ':') && +				((isspacechar(lineBuffer[offset + 2])) || +				(((lineBuffer[offset + 2] == '\\')) && +				(isspacechar(lineBuffer[offset + 3]))))) { +				// Colorize Regular Keyword +				styler.ColourTo(endPos, SCE_BAT_WORD); +				stopLineProcessing=true;  			} -		// Check for Regular Keyword in list -		} else if ((keywords.InList(wordBuffer)) && -			(continueProcessing)) { -			// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking -			if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || -				(CompareCaseInsensitive(wordBuffer, "goto") == 0) || -				(CompareCaseInsensitive(wordBuffer, "prompt") == 0) || -				(CompareCaseInsensitive(wordBuffer, "set") == 0)) { -				continueProcessing = false; + +			// Check for Hide Command (@ECHO OFF/ON) +			if (lineBuffer[offset] == '@') { +				styler.ColourTo(startLine + offset, SCE_BAT_HIDE); +				offset++;  			} -			// Identify External Command / Program Location for ERRORLEVEL, and EXIST -			if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || -				(CompareCaseInsensitive(wordBuffer, "exist") == 0)) { -				// Reset External Command / Program Location -				cmdLoc = offset; -				// Skip next spaces -				while ((cmdLoc < lengthLine) && -					(isspacechar(lineBuffer[cmdLoc]))) { -					cmdLoc++; -				} -				// Skip comparison -				while ((cmdLoc < lengthLine) && -					(!isspacechar(lineBuffer[cmdLoc]))) { -					cmdLoc++; -				} -				// Skip next spaces -				while ((cmdLoc < lengthLine) && -					(isspacechar(lineBuffer[cmdLoc]))) { -					cmdLoc++; +			// Skip next spaces +			while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { +				offset++; +			} + +			// Read remainder of line word-at-a-time or remainder-of-word-at-a-time +			while (offset < lengthLine  && !stopLineProcessing) { +				if (offset > startLine) { +					// Colorize Default Text +					styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);  				} -			// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH -			} else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) || -				(CompareCaseInsensitive(wordBuffer, "do") == 0) || -				(CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) || -				(CompareCaseInsensitive(wordBuffer, "lh") == 0)) { -				// Reset External Command / Program Location -				cmdLoc = offset; -				// Skip next spaces -				while ((cmdLoc < lengthLine) && -					(isspacechar(lineBuffer[cmdLoc]))) { -					cmdLoc++; +				// Copy word from Line Buffer into Word Buffer +				wbl = 0; +				for (; offset < lengthLine && wbl < 80 && +						!isspacechar(lineBuffer[offset]); wbl++, offset++) { +					wordBuffer[wbl] = static_cast<char>(tolower(lineBuffer[offset]));  				} -			} -			// Colorize Regular keyword -			styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); -			// No need to Reset Offset -		// Check for Special Keyword in list, External Command / Program, or Default Text -		} else if ((wordBuffer[0] != '%') && -				   (wordBuffer[0] != '!') && -			(!IsBOperator(wordBuffer[0])) && -			(continueProcessing)) { -			// Check for Special Keyword -			//     Affected Commands are in Length range 2-6 -			//     Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected -			sKeywordFound = false; -			for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) { +				wordBuffer[wbl] = '\0';  				wbo = 0; -				// Copy Keyword Length from Word Buffer into Special Keyword Buffer -				for (; wbo < keywordLength; wbo++) { -					sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]); + +				// Check for Comment - return if found +				if ((CompareCaseInsensitive(wordBuffer, "rem") == 0) && continueProcessing) { +					styler.ColourTo(endPos, SCE_BAT_COMMENT); +					break;  				} -				sKeywordBuffer[wbo] = '\0'; -				// Check for Special Keyword in list -				if ((keywords.InList(sKeywordBuffer)) && -					((IsBOperator(wordBuffer[wbo])) || -					(IsBSeparator(wordBuffer[wbo])))) { -					sKeywordFound = true; -					// ECHO requires no further Regular Keyword Checking -					if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { -						continueProcessing = false; +				// Check for Separator +				if (IsBSeparator(wordBuffer[0])) { +					// Check for External Command / Program +					if ((cmdLoc == offset - wbl) && +						((wordBuffer[0] == ':') || +						(wordBuffer[0] == '\\') || +						(wordBuffer[0] == '.'))) { +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 1); +						// Colorize External Command / Program +						if (!keywords2) { +							styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); +						} else if (keywords2.InList(wordBuffer)) { +							styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); +						} else { +							styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); +						} +						// Reset External Command / Program Location +						cmdLoc = offset; +					} else { +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 1); +						// Colorize Default Text +						styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);  					} -					// Colorize Special Keyword as Regular Keyword -					styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); -					// Reset Offset to re-process remainder of word -					offset -= (wbl - wbo); -				} -			} -			// Check for External Command / Program or Default Text -			if (!sKeywordFound) { -				wbo = 0; -				// Check for External Command / Program -				if (cmdLoc == offset - wbl) { -					// Read up to %, Operator or Separator -					while ((wbo < wbl) && -						(wordBuffer[wbo] != '%') && -						(wordBuffer[wbo] != '!') && -						(!IsBOperator(wordBuffer[wbo])) && -						(!IsBSeparator(wordBuffer[wbo]))) { -						wbo++; +				// Check for Regular Keyword in list +				} else if ((keywords.InList(wordBuffer)) && +					(continueProcessing)) { +					// ECHO, GOTO, PROMPT and SET require no further Regular Keyword Checking +					if ((CompareCaseInsensitive(wordBuffer, "echo") == 0) || +						(CompareCaseInsensitive(wordBuffer, "goto") == 0) || +						(CompareCaseInsensitive(wordBuffer, "prompt") == 0)) { +						continueProcessing = false;  					} -					// Reset External Command / Program Location -					cmdLoc = offset - (wbl - wbo); -					// Reset Offset to re-process remainder of word -					offset -= (wbl - wbo); -					// CHOICE requires no further Regular Keyword Checking -					if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { +					// SET requires additional processing for the assignment operator +					if (CompareCaseInsensitive(wordBuffer, "set") == 0) {  						continueProcessing = false; +						isNotAssigned=true;  					} -					// Check for START (and its switches) - What follows is External Command \ Program -					if (CompareCaseInsensitive(wordBuffer, "start") == 0) { +					// Identify External Command / Program Location for ERRORLEVEL, and EXIST +					if ((CompareCaseInsensitive(wordBuffer, "errorlevel") == 0) || +						(CompareCaseInsensitive(wordBuffer, "exist") == 0)) {  						// Reset External Command / Program Location  						cmdLoc = offset;  						// Skip next spaces @@ -269,37 +250,284 @@ static void ColouriseBatchLine(  							(isspacechar(lineBuffer[cmdLoc]))) {  							cmdLoc++;  						} -						// Reset External Command / Program Location if command switch detected -						if (lineBuffer[cmdLoc] == '/') { -							// Skip command switch -							while ((cmdLoc < lengthLine) && -								(!isspacechar(lineBuffer[cmdLoc]))) { -								cmdLoc++; +						// Skip comparison +						while ((cmdLoc < lengthLine) && +							(!isspacechar(lineBuffer[cmdLoc]))) { +							cmdLoc++; +						} +						// Skip next spaces +						while ((cmdLoc < lengthLine) && +							(isspacechar(lineBuffer[cmdLoc]))) { +							cmdLoc++; +						} +					// Identify External Command / Program Location for CALL, DO, LOADHIGH and LH +					} else if ((CompareCaseInsensitive(wordBuffer, "call") == 0) || +						(CompareCaseInsensitive(wordBuffer, "do") == 0) || +						(CompareCaseInsensitive(wordBuffer, "loadhigh") == 0) || +						(CompareCaseInsensitive(wordBuffer, "lh") == 0)) { +						// Reset External Command / Program Location +						cmdLoc = offset; +						// Skip next spaces +						while ((cmdLoc < lengthLine) && +							(isspacechar(lineBuffer[cmdLoc]))) { +							cmdLoc++; +						} +					} +					// Colorize Regular keyword +					styler.ColourTo(startLine + offset - 1, SCE_BAT_WORD); +					// No need to Reset Offset +				// Check for Special Keyword in list, External Command / Program, or Default Text +				} else if ((wordBuffer[0] != '%') && +						   (wordBuffer[0] != '!') && +					(!IsBOperator(wordBuffer[0])) && +					(continueProcessing)) { +					// Check for Special Keyword +					//     Affected Commands are in Length range 2-6 +					//     Good that ERRORLEVEL, EXIST, CALL, DO, LOADHIGH, and LH are unaffected +					sKeywordFound = false; +					for (Sci_PositionU keywordLength = 2; keywordLength < wbl && keywordLength < 7 && !sKeywordFound; keywordLength++) { +						wbo = 0; +						// Copy Keyword Length from Word Buffer into Special Keyword Buffer +						for (; wbo < keywordLength; wbo++) { +							sKeywordBuffer[wbo] = static_cast<char>(wordBuffer[wbo]); +						} +						sKeywordBuffer[wbo] = '\0'; +						// Check for Special Keyword in list +						if ((keywords.InList(sKeywordBuffer)) && +							((IsBOperator(wordBuffer[wbo])) || +							(IsBSeparator(wordBuffer[wbo])))) { +							sKeywordFound = true; +							// ECHO requires no further Regular Keyword Checking +							if (CompareCaseInsensitive(sKeywordBuffer, "echo") == 0) { +								continueProcessing = false;  							} -							// Skip next spaces -							while ((cmdLoc < lengthLine) && -								(isspacechar(lineBuffer[cmdLoc]))) { -								cmdLoc++; +							// Colorize Special Keyword as Regular Keyword +							styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_WORD); +							// Reset Offset to re-process remainder of word +							offset -= (wbl - wbo); +						} +					} +					// Check for External Command / Program or Default Text +					if (!sKeywordFound) { +						wbo = 0; +						// Check for External Command / Program +						if (cmdLoc == offset - wbl) { +							// Read up to %, Operator or Separator +							while ((wbo < wbl) && +								(((wordBuffer[wbo] != '%') && +								(wordBuffer[wbo] != '!') && +								(!IsBOperator(wordBuffer[wbo])) && +								(!IsBSeparator(wordBuffer[wbo]))))) { +								wbo++; +							} +							// Reset External Command / Program Location +							cmdLoc = offset - (wbl - wbo); +							// Reset Offset to re-process remainder of word +							offset -= (wbl - wbo); +							// CHOICE requires no further Regular Keyword Checking +							if (CompareCaseInsensitive(wordBuffer, "choice") == 0) { +								continueProcessing = false; +							} +							// Check for START (and its switches) - What follows is External Command \ Program +							if (CompareCaseInsensitive(wordBuffer, "start") == 0) { +								// Reset External Command / Program Location +								cmdLoc = offset; +								// Skip next spaces +								while ((cmdLoc < lengthLine) && +									(isspacechar(lineBuffer[cmdLoc]))) { +									cmdLoc++; +								} +								// Reset External Command / Program Location if command switch detected +								if (lineBuffer[cmdLoc] == '/') { +									// Skip command switch +									while ((cmdLoc < lengthLine) && +										(!isspacechar(lineBuffer[cmdLoc]))) { +										cmdLoc++; +									} +									// Skip next spaces +									while ((cmdLoc < lengthLine) && +										(isspacechar(lineBuffer[cmdLoc]))) { +										cmdLoc++; +									} +								} +							} +							// Colorize External Command / Program +							if (!keywords2) { +								styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); +							} else if (keywords2.InList(wordBuffer)) { +								styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); +							} else { +								styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT);  							} +							// No need to Reset Offset +						// Check for Default Text +						} else { +							// Read up to %, Operator or Separator +							while ((wbo < wbl) && +								(((wordBuffer[wbo] != '%') && +								(wordBuffer[wbo] != '!') && +								(!IsBOperator(wordBuffer[wbo])) && +								(!IsBSeparator(wordBuffer[wbo]))))) { +								wbo++; +							} +							// Colorize Default Text +							styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); +							// Reset Offset to re-process remainder of word +							offset -= (wbl - wbo); +						} +					} +				// Check for Argument  (%n), Environment Variable (%x...%) or Local Variable (%%a) +				} else if (wordBuffer[0] == '%') { +					// Colorize Default Text +					styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); +					wbo++; +					// Search to end of word for second % (can be a long path) +					while ((wbo < wbl) && +						(wordBuffer[wbo] != '%')) { +						wbo++; +					} +					// Check for Argument (%n) or (%*) +					if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) && +						(wordBuffer[wbo] != '%')) { +						// Check for External Command / Program +						if (cmdLoc == offset - wbl) { +							cmdLoc = offset - (wbl - 2); +						} +						// Colorize Argument +						styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 2); +					// Check for Expanded Argument (%~...) / Variable (%%~...) +					} else if (((wbl > 1) && (wordBuffer[1] == '~')) || +						((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) { +						// Check for External Command / Program +						if (cmdLoc == offset - wbl) { +							cmdLoc = offset - (wbl - wbo); +						} +						// Colorize Expanded Argument / Variable +						styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - wbo); +					// Check for Environment Variable (%x...%) +					} else if ((wordBuffer[1] != '%') && +						(wordBuffer[wbo] == '%')) { +						wbo++; +						// Check for External Command / Program +						if (cmdLoc == offset - wbl) { +							cmdLoc = offset - (wbl - wbo); +						} +						// Colorize Environment Variable +						styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - wbo); +					// Check for Local Variable (%%a) +					} else if ( +						(wbl > 2) && +						(wordBuffer[1] == '%') && +						(wordBuffer[2] != '%') && +						(!IsBOperator(wordBuffer[2])) && +						(!IsBSeparator(wordBuffer[2]))) { +						// Check for External Command / Program +						if (cmdLoc == offset - wbl) { +							cmdLoc = offset - (wbl - 3); +						} +						// Colorize Local Variable +						styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 3); +					} +				// Check for Environment Variable (!x...!) +				} else if (wordBuffer[0] == '!') { +					// Colorize Default Text +					styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); +					wbo++; +					// Search to end of word for second ! (can be a long path) +					while ((wbo < wbl) && +						(wordBuffer[wbo] != '!')) { +						wbo++; +					} +					if (wordBuffer[wbo] == '!') { +						wbo++; +						// Check for External Command / Program +						if (cmdLoc == offset - wbl) { +							cmdLoc = offset - (wbl - wbo);  						} +						// Colorize Environment Variable +						styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - wbo);  					} -					// Colorize External Command / Program -					if (!keywords2) { -						styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); -					} else if (keywords2.InList(wordBuffer)) { -						styler.ColourTo(startLine + offset - 1, SCE_BAT_COMMAND); +				// Check for Operator +				} else if (IsBOperator(wordBuffer[0])) { +					// Colorize Default Text +					styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); +					// Check for Comparison Operator +					if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) { +						// Identify External Command / Program Location for IF +						cmdLoc = offset; +						// Skip next spaces +						while ((cmdLoc < lengthLine) && +							(isspacechar(lineBuffer[cmdLoc]))) { +							cmdLoc++; +						} +						// Colorize Comparison Operator +						if (continueProcessing) +							styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR); +						else +							styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_DEFAULT); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 2); +					// Check for Pipe Operator +					} else if ((wordBuffer[0] == '|') && +								!(IsEscaped(lineBuffer,offset - wbl + wbo) || textQuoted(lineBuffer, offset - wbl) )) { +						// Reset External Command / Program Location +						cmdLoc = offset - wbl + 1; +						// Skip next spaces +						while ((cmdLoc < lengthLine) && +							(isspacechar(lineBuffer[cmdLoc]))) { +							cmdLoc++; +						} +						// Colorize Pipe Operator +						styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 1); +						continueProcessing = true; +					// Check for Other Operator  					} else { -						styler.ColourTo(startLine + offset - 1, SCE_BAT_DEFAULT); +						// Check for Operators: >, |, & +						if (((wordBuffer[0] == '>')|| +						   (wordBuffer[0] == ')')|| +						   (wordBuffer[0] == '(')|| +						   (wordBuffer[0] == '&' )) && +						   !(!continueProcessing && (IsEscaped(lineBuffer,offset - wbl + wbo) +						   || textQuoted(lineBuffer, offset - wbl) ))){ +							// Turn Keyword and External Command / Program checking back on +							continueProcessing = true; +							isNotAssigned=false; +						} +						// Colorize Other Operators +						// Do not Colorize Paranthesis, quoted text and escaped operators +						if (((wordBuffer[0] != ')') && (wordBuffer[0] != '(') +						&& !textQuoted(lineBuffer, offset - wbl)  && !IsEscaped(lineBuffer,offset - wbl + wbo)) +						&& !((wordBuffer[0] == '=') && !isNotAssigned )) +							styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); +						else +							styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_DEFAULT); +						// Reset Offset to re-process remainder of word +						offset -= (wbl - 1); + +						if ((wordBuffer[0] == '=') && isNotAssigned ){ +							isNotAssigned=false; +						}  					} -					// No need to Reset Offset  				// Check for Default Text  				} else {  					// Read up to %, Operator or Separator  					while ((wbo < wbl) && -						(wordBuffer[wbo] != '%') && +						((wordBuffer[wbo] != '%') &&  						(wordBuffer[wbo] != '!') &&  						(!IsBOperator(wordBuffer[wbo])) && -						(!IsBSeparator(wordBuffer[wbo]))) { +						(!IsBSeparator(wordBuffer[wbo])))) {  						wbo++;  					}  					// Colorize Default Text @@ -307,186 +535,31 @@ static void ColouriseBatchLine(  					// Reset Offset to re-process remainder of word  					offset -= (wbl - wbo);  				} -			} -		// Check for Argument  (%n), Environment Variable (%x...%) or Local Variable (%%a) -		} else if (wordBuffer[0] == '%') { -			// Colorize Default Text -			styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); -			wbo++; -			// Search to end of word for second % (can be a long path) -			while ((wbo < wbl) && -				(wordBuffer[wbo] != '%') && -				(!IsBOperator(wordBuffer[wbo])) && -				(!IsBSeparator(wordBuffer[wbo]))) { -				wbo++; -			} -			// Check for Argument (%n) or (%*) -			if (((Is0To9(wordBuffer[1])) || (wordBuffer[1] == '*')) && -				(wordBuffer[wbo] != '%')) { -				// Check for External Command / Program -				if (cmdLoc == offset - wbl) { -					cmdLoc = offset - (wbl - 2); -				} -				// Colorize Argument -				styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_IDENTIFIER); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 2); -			// Check for Expanded Argument (%~...) / Variable (%%~...) -			} else if (((wbl > 1) && (wordBuffer[1] == '~')) || -				((wbl > 2) && (wordBuffer[1] == '%') && (wordBuffer[2] == '~'))) { -				// Check for External Command / Program -				if (cmdLoc == offset - wbl) { -					cmdLoc = offset - (wbl - wbo); -				} -				// Colorize Expanded Argument / Variable -				styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - wbo); -			// Check for Environment Variable (%x...%) -			} else if ((wordBuffer[1] != '%') && -				(wordBuffer[wbo] == '%')) { -				wbo++; -				// Check for External Command / Program -				if (cmdLoc == offset - wbl) { -					cmdLoc = offset - (wbl - wbo); -				} -				// Colorize Environment Variable -				styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - wbo); -			// Check for Local Variable (%%a) -			} else if ( -				(wbl > 2) && -				(wordBuffer[1] == '%') && -				(wordBuffer[2] != '%') && -				(!IsBOperator(wordBuffer[2])) && -				(!IsBSeparator(wordBuffer[2]))) { -				// Check for External Command / Program -				if (cmdLoc == offset - wbl) { -					cmdLoc = offset - (wbl - 3); -				} -				// Colorize Local Variable -				styler.ColourTo(startLine + offset - 1 - (wbl - 3), SCE_BAT_IDENTIFIER); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 3); -			} -		// Check for Environment Variable (!x...!) -		} else if (wordBuffer[0] == '!') { -			// Colorize Default Text -			styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); -			wbo++; -			// Search to end of word for second ! (can be a long path) -			while ((wbo < wbl) && -				(wordBuffer[wbo] != '!') && -				(!IsBOperator(wordBuffer[wbo])) && -				(!IsBSeparator(wordBuffer[wbo]))) { -				wbo++; -			} -			if (wordBuffer[wbo] == '!') { -				wbo++; -				// Check for External Command / Program -				if (cmdLoc == offset - wbl) { -					cmdLoc = offset - (wbl - wbo); -				} -				// Colorize Environment Variable -				styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_IDENTIFIER); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - wbo); -			} -		// Check for Operator -		} else if (IsBOperator(wordBuffer[0])) { -			// Colorize Default Text -			styler.ColourTo(startLine + offset - 1 - wbl, SCE_BAT_DEFAULT); -			// Check for Comparison Operator -			if ((wordBuffer[0] == '=') && (wordBuffer[1] == '=')) { -				// Identify External Command / Program Location for IF -				cmdLoc = offset; -				// Skip next spaces -				while ((cmdLoc < lengthLine) && -					(isspacechar(lineBuffer[cmdLoc]))) { -					cmdLoc++; -				} -				// Colorize Comparison Operator -				styler.ColourTo(startLine + offset - 1 - (wbl - 2), SCE_BAT_OPERATOR); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 2); -			// Check for Pipe Operator -			} else if (wordBuffer[0] == '|') { -				// Reset External Command / Program Location -				cmdLoc = offset - wbl + 1; -				// Skip next spaces -				while ((cmdLoc < lengthLine) && -					(isspacechar(lineBuffer[cmdLoc]))) { -					cmdLoc++; +				// Skip next spaces - nothing happens if Offset was Reset +				while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { +					offset++;  				} -				// Colorize Pipe Operator -				styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 1); -			// Check for Other Operator -			} else { -				// Check for > Operator -				if (wordBuffer[0] == '>') { -					// Turn Keyword and External Command / Program checking back on -					continueProcessing = true; -				} -				// Colorize Other Operator -				styler.ColourTo(startLine + offset - 1 - (wbl - 1), SCE_BAT_OPERATOR); -				// Reset Offset to re-process remainder of word -				offset -= (wbl - 1); -			} -		// Check for Default Text -		} else { -			// Read up to %, Operator or Separator -			while ((wbo < wbl) && -				(wordBuffer[wbo] != '%') && -				(wordBuffer[wbo] != '!') && -				(!IsBOperator(wordBuffer[wbo])) && -				(!IsBSeparator(wordBuffer[wbo]))) { -				wbo++;  			} -			// Colorize Default Text -			styler.ColourTo(startLine + offset - 1 - (wbl - wbo), SCE_BAT_DEFAULT); -			// Reset Offset to re-process remainder of word -			offset -= (wbl - wbo); -		} -		// Skip next spaces - nothing happens if Offset was Reset -		while ((offset < lengthLine) && (isspacechar(lineBuffer[offset]))) { -			offset++; -		} -	} -	// Colorize Default Text for remainder of line - currently not lexed -	styler.ColourTo(endPos, SCE_BAT_DEFAULT); -} - -static void ColouriseBatchDoc( -    Sci_PositionU startPos, -    Sci_Position length, -    int /*initStyle*/, -    WordList *keywordlists[], -    Accessor &styler) { +			// Colorize Default Text for remainder of line - currently not lexed +			styler.ColourTo(endPos, SCE_BAT_DEFAULT); -	char lineBuffer[1024]; +			// handle line continuation for SET and ECHO commands except the last line and an empty line +			if (!continueProcessing && (i<startPos + length-1) && linePos>2) { +				Sci_PositionU lineContinuationPos; +				if (lineBuffer[linePos-2]=='\r') // Windows EOL +					lineContinuationPos=linePos-3; +				else +					lineContinuationPos=linePos-2; // Unix or Mac EOL +				if ((lineBuffer[lineContinuationPos]!='^') ||  // handle '^' line continuation +					IsEscaped(lineBuffer, lineContinuationPos) +					|| textQuoted(lineBuffer, lineContinuationPos)) +						continueProcessing=true; +			} -	styler.StartAt(startPos); -	styler.StartSegment(startPos); -	Sci_PositionU linePos = 0; -	Sci_PositionU startLine = startPos; -	for (Sci_PositionU i = startPos; i < startPos + length; i++) { -		lineBuffer[linePos++] = styler[i]; -		if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) { -			// End of line (or of line buffer) met, colourise it -			lineBuffer[linePos] = '\0'; -			ColouriseBatchLine(lineBuffer, linePos, startLine, i, keywordlists, styler);  			linePos = 0;  			startLine = i + 1;  		}  	} -	if (linePos > 0) {	// Last line does not have ending characters -		lineBuffer[linePos] = '\0'; -		ColouriseBatchLine(lineBuffer, linePos, startLine, startPos + length - 1, -		                   keywordlists, styler); -	}  }  static const char *const batchWordListDesc[] = { | 
