aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2015-01-08 09:55:35 +1100
committerNeil <nyamatongwe@gmail.com>2015-01-08 09:55:35 +1100
commitce581e18ef0b34f9c300a4ca8bd940148f2d7dc6 (patch)
tree3b151fe9d31cc9f5ac937a49a3031b1b5fc86fe7
parentd09c68b375cbd5720518f53822b3a46b56ae3b88 (diff)
downloadscintilla-mirror-ce581e18ef0b34f9c300a4ca8bd940148f2d7dc6.tar.gz
Feature [feature-requests:#1096]. Lexer added for Tektronix extended hex files.
From danselmi.
-rw-r--r--doc/ScintillaHistory.html3
-rw-r--r--include/SciLexer.h2
-rw-r--r--include/Scintilla.iface4
-rw-r--r--lexers/LexHex.cxx203
-rw-r--r--src/Catalogue.cxx1
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);