diff options
author | Neil <nyamatongwe@gmail.com> | 2015-01-08 09:55:35 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2015-01-08 09:55:35 +1100 |
commit | ce581e18ef0b34f9c300a4ca8bd940148f2d7dc6 (patch) | |
tree | 3b151fe9d31cc9f5ac937a49a3031b1b5fc86fe7 | |
parent | d09c68b375cbd5720518f53822b3a46b56ae3b88 (diff) | |
download | scintilla-mirror-ce581e18ef0b34f9c300a4ca8bd940148f2d7dc6.tar.gz |
Feature [feature-requests:#1096]. Lexer added for Tektronix extended hex files.
From danselmi.
-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); |