diff options
| -rw-r--r-- | doc/ScintillaHistory.html | 3 | ||||
| -rw-r--r-- | include/SciLexer.h | 2 | ||||
| -rw-r--r-- | include/Scintilla.iface | 4 | ||||
| -rw-r--r-- | lexers/LexHex.cxx | 203 | ||||
| -rw-r--r-- | src/Catalogue.cxx | 1 | 
5 files changed, 212 insertions, 1 deletions
| diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html index 1bb8c4de9..c4d420452 100644 --- a/doc/ScintillaHistory.html +++ b/doc/ScintillaHistory.html @@ -484,10 +484,11 @@  	Released 2 December 2014.  	</li>  	<li> -	Lexers added for Motorola S-Record files and Intel hex files with folding for Intel hex files. +	Lexers added for Motorola S-Record files, Intel hex files, and Tektronix extended hex files with folding for Intel hex files.  	<a href="http://sourceforge.net/p/scintilla/feature-requests/1091/">Feature #1091.</a>  	<a href="http://sourceforge.net/p/scintilla/feature-requests/1093/">Feature #1093.</a>  	<a href="http://sourceforge.net/p/scintilla/feature-requests/1095/">Feature #1095.</a> +	<a href="http://sourceforge.net/p/scintilla/feature-requests/1096/">Feature #1096.</a>  	</li>  	<li>  	C++ folder allows folding on square brackets '['. diff --git a/include/SciLexer.h b/include/SciLexer.h index 8547bf5c2..acbe6ab8d 100644 --- a/include/SciLexer.h +++ b/include/SciLexer.h @@ -131,6 +131,7 @@  #define SCLEX_BIBTEX 116  #define SCLEX_SREC 117  #define SCLEX_IHEX 118 +#define SCLEX_THEX 119  #define SCLEX_AUTOMATIC 1000  #define SCE_P_DEFAULT 0  #define SCE_P_COMMENTLINE 1 @@ -1765,6 +1766,7 @@  #define SCE_HEX_DATA_EMPTY 14  #define SCE_HEX_CHECKSUM 15  #define SCE_HEX_CHECKSUM_WRONG 16 +#define SCE_HEX_RECTYPE_UNKNOWN 17  /* --Autogenerated -- end of section automatically generated from Scintilla.iface */  #endif diff --git a/include/Scintilla.iface b/include/Scintilla.iface index e35b16f16..a51c2a31e 100644 --- a/include/Scintilla.iface +++ b/include/Scintilla.iface @@ -2721,6 +2721,7 @@ val SCLEX_REGISTRY=115  val SCLEX_BIBTEX=116  val SCLEX_SREC=117  val SCLEX_IHEX=118 +val SCLEX_THEX=119  # When a lexer specifies its language as SCLEX_AUTOMATIC it receives a  # value assigned in sequence from SCLEX_AUTOMATIC+1. @@ -4568,8 +4569,11 @@ val SCE_HEX_DATA_UNKNOWN=13  val SCE_HEX_DATA_EMPTY=14  val SCE_HEX_CHECKSUM=15  val SCE_HEX_CHECKSUM_WRONG=16 +val SCE_HEX_RECTYPE_UNKNOWN=17  # Lexical state for SCLEX_IHEX (shared with Srec)  lex IHex=SCLEX_IHEX SCE_HEX_ +# Lexical state for SCLEX_THEX (shared with Srec) +lex THex=SCLEX_THEX SCE_HEX_  # Events diff --git a/lexers/LexHex.cxx b/lexers/LexHex.cxx index b8988e52c..5aa41dd8a 100644 --- a/lexers/LexHex.cxx +++ b/lexers/LexHex.cxx @@ -62,6 +62,27 @@   *   Any line, which is not a record (blank lines and lines starting with a   *   character other than ':'), leaves the fold level unchanged.   * + *  Tektronix extended HEX + * =============================== + * + * Each record (line) is built as follows: + * + *    field       digits          states + * + *  +----------+ + *  | start    |  1 ('%')         SCE_HEX_RECSTART + *  +----------+ + *  | length   |  2               SCE_HEX_BYTECOUNT, SCE_HEX_BYTECOUNT_WRONG + *  +----------+ + *  | type     |  1               SCE_HEX_RECTYPE, SCE_HEX_RECTYPE_UNKNOWN + *  +----------+ + *  | checksum |  2               SCE_HEX_CHECKSUM, SCE_HEX_CHECKSUM_WRONG + *  +----------+ + *  | address  |  9               SCE_HEX_DATAADDRESS + *  +----------+ + *  | data     |  0..241          SCE_HEX_DATA_ODD, SCE_HEX_DATA_EVEN + *  +----------+ + *   *   *  General notes for all lexers   * =============================== @@ -121,6 +142,11 @@ static int GetIHexRequiredDataFieldSize(unsigned int recStartPos, Accessor &styl  static int GetIHexChecksum(unsigned int recStartPos, Accessor &styler);  static int CalcIHexChecksum(unsigned int recStartPos, Accessor &styler); +static int GetTHexDigitCount(unsigned int recStartPos, Accessor &styler); +static int CountTHexDigitCount(unsigned int recStartPos, Accessor &styler); +static int GetTHexChecksum(unsigned int recStartPos, Accessor &styler); +static int CalcTHexChecksum(unsigned int recStartPos, Accessor &styler); +  static inline bool IsNewline(const int ch)  {      return (ch == '\n' || ch == '\r'); @@ -472,6 +498,82 @@ static int CalcIHexChecksum(unsigned int recStartPos, Accessor &styler)  	return CalcChecksum(recStartPos + 1, 8 + byteCount * 2, true, styler);  } + +// Get the value of the "record length" field, it counts the number of digits in +// the record excluding the percent. +static int GetTHexDigitCount(unsigned int recStartPos, Accessor &styler) +{ +	int val = GetHexaChar(recStartPos + 1, styler); +	if (val < 0) +	       val = 0; + +	return val; +} +// Count the number of digits in this record. Has to +// be equal to the "record length" field value. +static int CountTHexDigitCount(unsigned int recStartPos, Accessor &styler) +{ +	unsigned int pos; + +	pos = recStartPos+1; + +	while (!IsNewline(styler.SafeGetCharAt(pos, '\n'))) { +		pos++; +	} + +	return static_cast<int>(pos - (recStartPos+1)); +} +// Get the value of the "checksum" field. +static int GetTHexChecksum(unsigned int recStartPos, Accessor &styler) +{ +    return GetHexaChar(recStartPos+4, styler); +} + +static int GetHexaNibble(char hd) +{ +	int hexValue = 0; + +	if (hd >= '0' && hd <= '9') { +		hexValue += hd - '0'; +	} else if (hd >= 'A' && hd <= 'F') { +		hexValue += hd - 'A' + 10; +	} else if (hd >= 'a' && hd <= 'f') { +		hexValue += hd - 'a' + 10; +	} else { +		return -1; +	} + +	return hexValue; +} +// Calculate the checksum of the record (excluding the checksum field). +static int CalcTHexChecksum(unsigned int recStartPos, Accessor &styler) +{ +	unsigned int pos = recStartPos +1; +	unsigned int length = GetHexaChar(pos, styler); +	int cs = GetHexaNibble(styler.SafeGetCharAt(pos++));//length +	cs += GetHexaNibble(styler.SafeGetCharAt(pos++));//length + +	cs += GetHexaNibble(styler.SafeGetCharAt(pos++));//type + +    pos += 2;// jump over CS field +    //while(!IsNewline(styler.SafeGetCharAt(pos, '\n')){ + +	for (; pos <= recStartPos + length; ++pos) { +		int val = GetHexaNibble(styler.SafeGetCharAt(pos)); + +		if (val < 0) { +			return val; +		} + +		// overflow does not matter +		cs += val; +	} + +    // low byte +    return cs & 0xFF; + +} +  static void ColouriseSrecDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)  {  	StyleContext sc(startPos, length, initStyle, styler); @@ -728,5 +830,106 @@ static void FoldIHexDoc(unsigned int startPos, int length, int, WordList *[], Ac  	}  } +static void ColouriseTHexDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) +{ +	StyleContext sc(startPos, length, initStyle, styler); + +	while (sc.More()) { +		unsigned int recStartPos; +		int digitCount; +		int cs1, cs2; + +		switch (sc.state) { +			case SCE_HEX_DEFAULT: +				if (sc.atLineStart && sc.Match('%')) { +					sc.SetState(SCE_HEX_RECSTART); +				} +				ForwardWithinLine(sc); +				break; + +			case SCE_HEX_RECSTART: + +				recStartPos = sc.currentPos - 1; + +				if (GetTHexDigitCount(recStartPos, styler) == CountTHexDigitCount(recStartPos, styler)) { +					sc.SetState(SCE_HEX_BYTECOUNT); +				} else { +					sc.SetState(SCE_HEX_BYTECOUNT_WRONG); +				} + +				ForwardWithinLine(sc, 2); +				break; + +			case SCE_HEX_BYTECOUNT: +			case SCE_HEX_BYTECOUNT_WRONG: +				//recStartPos = sc.currentPos - 3; +				if (sc.Match('6') || sc.Match('8')) { +					sc.SetState(SCE_HEX_RECTYPE); +				} else { +					sc.SetState(SCE_HEX_RECTYPE_UNKNOWN); +				} + +				ForwardWithinLine(sc); +				break; + +			case SCE_HEX_RECTYPE: +			case SCE_HEX_RECTYPE_UNKNOWN: +				recStartPos = sc.currentPos - 4; +				cs1 = CalcTHexChecksum(recStartPos, styler); +				cs2 = GetTHexChecksum(recStartPos, styler); + +				if (cs1 != cs2 || cs1 < 0 || cs2 < 0) { +					sc.SetState(SCE_HEX_CHECKSUM_WRONG); +				} else { +					sc.SetState(SCE_HEX_CHECKSUM); +				} + +				ForwardWithinLine(sc, 2); +				break; + + +			case SCE_HEX_CHECKSUM: +			case SCE_HEX_CHECKSUM_WRONG: +				//recStartPos = sc.currentPos - 6; +				sc.SetState(SCE_HEX_DATAADDRESS); +				ForwardWithinLine(sc, 9); +				break; +			case SCE_HEX_NOADDRESS: +			case SCE_HEX_DATAADDRESS: +				recStartPos = sc.currentPos - 15; +				digitCount = GetTHexDigitCount(recStartPos, styler) - 14; + +				sc.SetState(SCE_HEX_DATA_ODD); + +				for (int i = 0; i < digitCount; i++) { +					if ((i & 0x3) == 0) { +						sc.SetState(SCE_HEX_DATA_ODD); +					} else if ((i & 0x3) == 2) { +						sc.SetState(SCE_HEX_DATA_EVEN); +					} + +					if (!ForwardWithinLine(sc)) { +						break; +					} +				} +				break; + +			case SCE_HEX_DATA_ODD: +			case SCE_HEX_DATA_EVEN: +			case SCE_HEX_DATA_EMPTY: +			case SCE_HEX_EXTENDEDADDRESS: +			case SCE_HEX_STARTADDRESS: +			case SCE_HEX_DATA_UNKNOWN: + +				// line too long +				sc.SetState(SCE_HEX_DATA_UNKNOWN); +				ForwardWithinLine(sc); +				break; +		} +	} +	sc.Complete(); +} +  LexerModule lmSrec(SCLEX_SREC, ColouriseSrecDoc, "srec", 0, NULL);  LexerModule lmIHex(SCLEX_IHEX, ColouriseIHexDoc, "ihex", FoldIHexDoc, NULL); +LexerModule lmTHex(SCLEX_THEX, ColouriseTHexDoc, "thex", 0, NULL); diff --git a/src/Catalogue.cxx b/src/Catalogue.cxx index 5e0bfd790..079246c90 100644 --- a/src/Catalogue.cxx +++ b/src/Catalogue.cxx @@ -183,6 +183,7 @@ int Scintilla_LinkLexers() {  	LINK_LEXER(lmTCL);  	LINK_LEXER(lmTCMD);  	LINK_LEXER(lmTeX); +	LINK_LEXER(lmTHex);  	LINK_LEXER(lmTxt2tags);  	LINK_LEXER(lmVB);  	LINK_LEXER(lmVBScript); | 
