aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorNeil <nyamatongwe@gmail.com>2016-09-22 14:15:35 +1000
committerNeil <nyamatongwe@gmail.com>2016-09-22 14:15:35 +1000
commite0900d15800a7ab023a107b8f4dd612f9164e3a8 (patch)
tree27b24934dd2ce530f91ce5247c96ec4091786ba0
parent4dff76d6ab5c2f08c128ee157bdefda9b2894fa4 (diff)
downloadscintilla-mirror-e0900d15800a7ab023a107b8f4dd612f9164e3a8.tar.gz
Baan lexer changed significantly with more lexical states, keyword sets, and
support for abridged keywords.
-rw-r--r--doc/ScintillaHistory.html4
-rw-r--r--include/SciLexer.h14
-rw-r--r--include/Scintilla.iface14
-rw-r--r--lexers/LexBaan.cxx602
4 files changed, 578 insertions, 56 deletions
diff --git a/doc/ScintillaHistory.html b/doc/ScintillaHistory.html
index 995fed33c..072de2c70 100644
--- a/doc/ScintillaHistory.html
+++ b/doc/ScintillaHistory.html
@@ -530,6 +530,10 @@
matching keywords that have particular prefixes and/or suffixes.
</li>
<li>
+ The Baan lexer was changed significantly with more lexical states, keyword sets,
+ and support for abridged keywords.
+ </li>
+ <li>
The Progress lexer "progress" has been replaced with a new lexer "abl"
(Advanced Business Language)
with a different set of lexical states and more functionality.
diff --git a/include/SciLexer.h b/include/SciLexer.h
index cb38fff99..0eb0b2956 100644
--- a/include/SciLexer.h
+++ b/include/SciLexer.h
@@ -599,6 +599,20 @@
#define SCE_BAAN_IDENTIFIER 8
#define SCE_BAAN_STRINGEOL 9
#define SCE_BAAN_WORD2 10
+#define SCE_BAAN_WORD3 11
+#define SCE_BAAN_WORD4 12
+#define SCE_BAAN_WORD5 13
+#define SCE_BAAN_WORD6 14
+#define SCE_BAAN_WORD7 15
+#define SCE_BAAN_WORD8 16
+#define SCE_BAAN_WORD9 17
+#define SCE_BAAN_TABLEDEF 18
+#define SCE_BAAN_TABLESQL 19
+#define SCE_BAAN_FUNCTION 20
+#define SCE_BAAN_DOMDEF 21
+#define SCE_BAAN_FUNCDEF 22
+#define SCE_BAAN_OBJECTDEF 23
+#define SCE_BAAN_DEFINEDEF 24
#define SCE_LISP_DEFAULT 0
#define SCE_LISP_COMMENT 1
#define SCE_LISP_NUMBER 2
diff --git a/include/Scintilla.iface b/include/Scintilla.iface
index 072173bc8..27d1d7513 100644
--- a/include/Scintilla.iface
+++ b/include/Scintilla.iface
@@ -3366,6 +3366,20 @@ val SCE_BAAN_OPERATOR=7
val SCE_BAAN_IDENTIFIER=8
val SCE_BAAN_STRINGEOL=9
val SCE_BAAN_WORD2=10
+val SCE_BAAN_WORD3=11
+val SCE_BAAN_WORD4=12
+val SCE_BAAN_WORD5=13
+val SCE_BAAN_WORD6=14
+val SCE_BAAN_WORD7=15
+val SCE_BAAN_WORD8=16
+val SCE_BAAN_WORD9=17
+val SCE_BAAN_TABLEDEF=18
+val SCE_BAAN_TABLESQL=19
+val SCE_BAAN_FUNCTION=20
+val SCE_BAAN_DOMDEF=21
+val SCE_BAAN_FUNCDEF=22
+val SCE_BAAN_OBJECTDEF=23
+val SCE_BAAN_DEFINEDEF=24
# Lexical states for SCLEX_LISP
lex Lisp=SCLEX_LISP SCE_LISP_
val SCE_LISP_DEFAULT=0
diff --git a/lexers/LexBaan.cxx b/lexers/LexBaan.cxx
index 8da2f3a3e..99141c2d0 100644
--- a/lexers/LexBaan.cxx
+++ b/lexers/LexBaan.cxx
@@ -1,134 +1,568 @@
// Scintilla source code edit control
/** @file LexBaan.cxx
- ** Lexer for Baan.
- ** Based heavily on LexCPP.cxx
- **/
+** Lexer for Baan.
+** Based heavily on LexCPP.cxx
+**/
// Copyright 2001- by Vamsi Potluru <vamsi@who.net> & Praveen Ambekar <ambekarpraveen@yahoo.com>
// The License.txt file describes the conditions under which this software may be distributed.
+// C standard library
#include <stdlib.h>
#include <string.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <ctype.h>
+// C++ wrappers of C standard library
+#include <cassert>
+
+// C++ standard library
+#include <string>
+#include <map>
+
+// Scintilla headers
+
+// Non-platform-specific headers
+
+// include
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
+// lexlib
#include "WordList.h"
#include "LexAccessor.h"
-#include "Accessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"
+#include "OptionSet.h"
-#ifdef SCI_NAMESPACE
+# ifdef SCI_NAMESPACE
using namespace Scintilla;
-#endif
+# endif
+
+namespace {
+ // Use an unnamed namespace to protect the functions and classes from name conflicts
+
+// Options used for LexerBaan
+struct OptionsBaan {
+ bool fold;
+ bool foldComment;
+ bool foldPreprocessor;
+ bool foldCompact;
+ bool baanFoldSyntaxBased;
+ bool baanFoldKeywordsBased;
+ bool baanStylingWithinPreprocessor;
+ OptionsBaan() {
+ fold = false;
+ foldComment = false;
+ foldPreprocessor = false;
+ foldCompact = false;
+ baanFoldSyntaxBased = false;
+ baanFoldKeywordsBased = false;
+ baanStylingWithinPreprocessor = false;
+ }
+};
+
+const char *const baanWordLists[] = {
+ "Baan & BaanSQL Reserved Keywords ",
+ "Baan Standard functions",
+ "Baan Functions Abridged",
+ "Baan Main Sections ",
+ "Baan Sub Sections",
+ "PreDefined Variables",
+ "PreDefined Attributes",
+ "Enumerates",
+ 0,
+};
+
+struct OptionSetBaan : public OptionSet<OptionsBaan> {
+ OptionSetBaan() {
+ DefineProperty("fold", &OptionsBaan::fold);
+
+ DefineProperty("fold.comment", &OptionsBaan::foldComment);
+
+ DefineProperty("fold.preprocessor", &OptionsBaan::foldPreprocessor);
+
+ DefineProperty("fold.compact", &OptionsBaan::foldCompact);
+
+ DefineProperty("fold.baan.syntax.based", &OptionsBaan::baanFoldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding, which is folding based on '{' & '('.");
+
+ DefineProperty("fold.baan.keywords.based", &OptionsBaan::baanFoldKeywordsBased,
+ "Set this property to 0 to disable keywords based folding, which is folding based on "
+ " for, if, on (case), repeat, select, while and fold ends based on endfor, endif, endcase, until, endselect, endwhile respectively.");
+
+ DefineProperty("lexer.baan.styling.within.preprocessor", &OptionsBaan::baanStylingWithinPreprocessor,
+ "For Baan code, determines whether all preprocessor code is styled in the "
+ "preprocessor style (0, the default) or only from the initial # to the end "
+ "of the command word(1).");
+
+ DefineWordListSets(baanWordLists);
+ }
+};
static inline bool IsAWordChar(const int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$' || ch == ':');
+ return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '$');
}
static inline bool IsAWordStart(const int ch) {
return (ch < 0x80) && (isalnum(ch) || ch == '_');
}
-static void ColouriseBaanDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
+static inline bool IsAnOperator(int ch) {
+ if (IsAlphaNumeric(ch))
+ return false;
+ if (ch == '#' || ch == '^' || ch == '&' || ch == '*' ||
+ ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
+ ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
+ ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
+ ch == '?' || ch == '!' || ch == '"' || ch == '~' ||
+ ch == '\\')
+ return true;
+ return false;
+}
+
+static inline int IsAnyOtherIdentifier(char *s, int sLength) {
+
+ /* IsAnyOtherIdentifier uses standard templates used in baan.
+ The matching template is shown as comments just above the return condition.
+ ^ - refers to any character [a-z].
+ # - refers to any number [0-9].
+ Other characters shown are compared as is.
+ Tried implementing with Regex... it was too complicated for me.
+ Any other implementation suggestion welcome.
+ */
+ switch (sLength) {
+ case 8:
+ if (isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
+ //^^^^^###
+ return(SCE_BAAN_TABLEDEF);
+ }
+ break;
+ case 9:
+ if (s[0] == 't' && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && isalpha(s[5]) && IsADigit(s[6]) && IsADigit(s[7]) && IsADigit(s[8])) {
+ //t^^^^^###
+ return(SCE_BAAN_TABLEDEF);
+ }
+ else if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
+ //^^^^^###.
+ return(SCE_BAAN_TABLESQL);
+ }
+ break;
+ case 13:
+ if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
+ //^^^^^###.****
+ return(SCE_BAAN_TABLESQL);
+ }
+ else if (s[0] == 'r' && s[1] == 'c' && s[2] == 'd' && s[3] == '.' && s[4] == 't' && isalpha(s[5]) && isalpha(s[6]) && isalpha(s[7]) && isalpha(s[8]) && isalpha(s[9]) && IsADigit(s[10]) && IsADigit(s[11]) && IsADigit(s[12])) {
+ //rcd.t^^^^^###
+ return(SCE_BAAN_TABLEDEF);
+ }
+ break;
+ case 14:
+ case 15:
+ if (s[8] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
+ if (s[13] != ':') {
+ //^^^^^###.******
+ return(SCE_BAAN_TABLESQL);
+ }
+ }
+ break;
+ case 16:
+ case 17:
+ if (s[8] == '.' && s[9] == '_' && s[10] == 'i' && s[11] == 'n' && s[12] == 'd' && s[13] == 'e' && s[14] == 'x' && IsADigit(s[15]) && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
+ //^^^^^###._index##
+ return(SCE_BAAN_TABLEDEF);
+ }
+ else if (s[8] == '.' && s[9] == '_' && s[10] == 'c' && s[11] == 'o' && s[12] == 'm' && s[13] == 'p' && s[14] == 'n' && s[15] == 'r' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[5]) && IsADigit(s[6]) && IsADigit(s[7])) {
+ //^^^^^###._compnr
+ return(SCE_BAAN_TABLEDEF);
+ }
+ break;
+ default:
+ break;
+ }
+ if (sLength > 14 && s[5] == '.' && s[6] == 'd' && s[7] == 'l' && s[8] == 'l' && s[13] == '.' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && IsADigit(s[9]) && IsADigit(s[10]) && IsADigit(s[11]) && IsADigit(s[12])) {
+ //^^^^^.dll####.
+ return(SCE_BAAN_FUNCTION);
+ }
+ else if (sLength > 15 && s[2] == 'i' && s[3] == 'n' && s[4] == 't' && s[5] == '.' && s[6] == 'd' && s[7] == 'l' && s[8] == 'l' && isalpha(s[0]) && isalpha(s[1]) && isalpha(s[9]) && isalpha(s[10]) && isalpha(s[11]) && isalpha(s[12]) && isalpha(s[13])) {
+ //^^int.dll^^^^^.
+ return(SCE_BAAN_FUNCTION);
+ }
+ else if (sLength > 11 && s[0] == 'i' && s[10] == '.' && isalpha(s[1]) && isalpha(s[2]) && isalpha(s[3]) && isalpha(s[4]) && isalpha(s[5]) && IsADigit(s[6]) && IsADigit(s[7]) && IsADigit(s[8]) && IsADigit(s[9])) {
+ //i^^^^^####.
+ return(SCE_BAAN_FUNCTION);
+ }
+
+ return(SCE_BAAN_DEFAULT);
+}
+
+static inline bool IsCommentLine(Sci_Position line, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
+ for (Sci_Position i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ if (ch == '|')
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+static inline bool IsPreProcLine(Sci_Position line, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+ Sci_Position pos = styler.LineStart(line);
+ Sci_Position eol_pos = styler.LineStart(line + 1) - 1;
+ for (Sci_Position i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ if (ch == '#')
+ return true;
+ else if (ch != ' ' && ch != '\t')
+ return false;
+ }
+ return false;
+}
+
+static inline int ToLowerCase(int c) {
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+static inline bool wordInArray(const std::string& value, std::string *array, int length)
+{
+ for (int i = 0; i < length; i++)
+ {
+ if (value == array[i])
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+class WordListAbridged : public WordList {
+public:
+ WordListAbridged() {
+ kwAbridged = false;
+ kwHasSection = false;
+ };
+ ~WordListAbridged() {
+ Clear();
+ };
+ bool kwAbridged;
+ bool kwHasSection;
+ bool Contains(const char *s) {
+ return kwAbridged ? InListAbridged(s, '~') : InList(s);
+ };
+};
+
+}
+
+class LexerBaan : public ILexer {
+ WordListAbridged keywords;
+ WordListAbridged keywords2;
+ WordListAbridged keywords3;
+ WordListAbridged keywords4;
+ WordListAbridged keywords5;
+ WordListAbridged keywords6;
+ WordListAbridged keywords7;
+ WordListAbridged keywords8;
+ WordListAbridged keywords9;
+ OptionsBaan options;
+ OptionSetBaan osBaan;
+public:
+ LexerBaan() {
+ }
+
+ virtual ~LexerBaan() {
+ }
+
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+
+ void SCI_METHOD Release() {
+ delete this;
+ }
+
+ const char * SCI_METHOD PropertyNames() {
+ return osBaan.PropertyNames();
+ }
+
+ int SCI_METHOD PropertyType(const char * name) {
+ return osBaan.PropertyType(name);
+ }
+
+ const char * SCI_METHOD DescribeProperty(const char * name) {
+ return osBaan.DescribeProperty(name);
+ }
+
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osBaan.DescribeWordListSets();
+ }
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
+ Sci_Position SCI_METHOD WordListSet(int n, const char *wl);
+
+ void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
+
+ void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return NULL;
+ }
+
+ static ILexer * LexerFactoryBaan() {
+ return new LexerBaan();
+ }
+};
+
+Sci_Position SCI_METHOD LexerBaan::PropertySet(const char *key, const char *val) {
+ if (osBaan.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+Sci_Position SCI_METHOD LexerBaan::WordListSet(int n, const char *wl) {
+ WordListAbridged *WordListAbridgedN = 0;
+ switch (n) {
+ case 0:
+ WordListAbridgedN = &keywords;
+ break;
+ case 1:
+ WordListAbridgedN = &keywords2;
+ break;
+ case 2:
+ WordListAbridgedN = &keywords3;
+ break;
+ case 3:
+ WordListAbridgedN = &keywords4;
+ break;
+ case 4:
+ WordListAbridgedN = &keywords5;
+ break;
+ case 5:
+ WordListAbridgedN = &keywords6;
+ break;
+ case 6:
+ WordListAbridgedN = &keywords7;
+ break;
+ case 7:
+ WordListAbridgedN = &keywords8;
+ break;
+ case 8:
+ WordListAbridgedN = &keywords9;
+ break;
+ }
+ Sci_Position firstModification = -1;
+ if (WordListAbridgedN) {
+ WordListAbridged wlNew;
+ wlNew.Set(wl);
+ if (*WordListAbridgedN != wlNew) {
+ WordListAbridgedN->Set(wl);
+ WordListAbridgedN->kwAbridged = strchr(wl, '~') != NULL;
+ WordListAbridgedN->kwHasSection = strchr(wl, ':') != NULL;
+
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerBaan::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
if (initStyle == SCE_BAAN_STRINGEOL) // Does not leak onto next line
initStyle = SCE_BAAN_DEFAULT;
int visibleChars = 0;
+ bool lineHasDomain = false;
+ bool lineHasFunction = false;
+ bool lineHasPreProc = false;
+ bool lineIgnoreString = false;
+ bool lineHasDefines = false;
+ LexAccessor styler(pAccess);
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
- if (sc.state == SCE_BAAN_OPERATOR) {
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_BAAN_OPERATOR:
sc.SetState(SCE_BAAN_DEFAULT);
- } else if (sc.state == SCE_BAAN_NUMBER) {
+ break;
+ case SCE_BAAN_NUMBER:
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_BAAN_DEFAULT);
}
- } else if (sc.state == SCE_BAAN_IDENTIFIER) {
+ break;
+ case SCE_BAAN_IDENTIFIER:
if (!IsAWordChar(sc.ch)) {
- char s[100];
+ char s[1000];
+ char s1[1000];
sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
+ if (sc.ch == ':') {
+ memcpy(s1, s, sizeof(s));
+ s1[sc.LengthCurrent()] = sc.ch;
+ s1[sc.LengthCurrent() + 1] = '\0';
+ }
+ if ((keywords.kwHasSection && (sc.ch == ':')) ? keywords.Contains(s1) : keywords.Contains(s)) {
sc.ChangeState(SCE_BAAN_WORD);
- } else if (keywords2.InList(s)) {
+ if (0 == strcmp(s, "domain")) {
+ lineHasDomain = true;
+ }
+ else if (0 == strcmp(s, "function")) {
+ lineHasFunction = true;
+ }
+ }
+ else if ((keywords2.kwHasSection && (sc.ch == ':')) ? keywords2.Contains(s1) : keywords2.Contains(s)) {
sc.ChangeState(SCE_BAAN_WORD2);
}
+ else if ((keywords3.kwHasSection && (sc.ch == ':')) ? keywords3.Contains(s1) : keywords3.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD3);
+ }
+ else if ((keywords4.kwHasSection && (sc.ch == ':')) ? keywords4.Contains(s1) : keywords4.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD4);
+ }
+ else if ((keywords5.kwHasSection && (sc.ch == ':')) ? keywords5.Contains(s1) : keywords5.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD5);
+ }
+ else if ((keywords6.kwHasSection && (sc.ch == ':')) ? keywords6.Contains(s1) : keywords6.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD6);
+ }
+ else if ((keywords7.kwHasSection && (sc.ch == ':')) ? keywords7.Contains(s1) : keywords7.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD7);
+ }
+ else if ((keywords8.kwHasSection && (sc.ch == ':')) ? keywords8.Contains(s1) : keywords8.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD8);
+ }
+ else if ((keywords9.kwHasSection && (sc.ch == ':')) ? keywords9.Contains(s1) : keywords9.Contains(s)) {
+ sc.ChangeState(SCE_BAAN_WORD9);
+ }
+ else if (lineHasDomain) {
+ sc.ChangeState(SCE_BAAN_DOMDEF);
+ lineHasDomain = false;
+ }
+ else if (lineHasFunction) {
+ sc.ChangeState(SCE_BAAN_FUNCDEF);
+ lineHasFunction = false;
+ }
+ else if (lineHasPreProc) {
+ sc.ChangeState(SCE_BAAN_OBJECTDEF);
+ lineHasPreProc = false;
+ }
+ else if (lineHasDefines) {
+ sc.ChangeState(SCE_BAAN_DEFINEDEF);
+ lineHasDefines = false;
+ }
+ else {
+ int state = IsAnyOtherIdentifier(s, sc.LengthCurrent());
+ if (state > 0) {
+ sc.ChangeState(state);
+ }
+ }
sc.SetState(SCE_BAAN_DEFAULT);
}
- } else if (sc.state == SCE_BAAN_PREPROCESSOR) {
- if (stylingWithinPreprocessor) {
- if (IsASpace(sc.ch)) {
+ break;
+ case SCE_BAAN_PREPROCESSOR:
+ if (options.baanStylingWithinPreprocessor) {
+ if (IsASpace(sc.ch) || IsAnOperator(sc.ch)) {
sc.SetState(SCE_BAAN_DEFAULT);
}
- } else {
+ }
+ else {
if (sc.atLineEnd && (sc.chNext != '^')) {
sc.SetState(SCE_BAAN_DEFAULT);
}
}
- } else if (sc.state == SCE_BAAN_COMMENT) {
+ break;
+ case SCE_BAAN_COMMENT:
if (sc.atLineEnd) {
sc.SetState(SCE_BAAN_DEFAULT);
}
- } else if (sc.state == SCE_BAAN_COMMENTDOC) {
+ break;
+ case SCE_BAAN_COMMENTDOC:
if (sc.MatchIgnoreCase("enddllusage")) {
- for (unsigned int i = 0; i < 10; i++){
+ for (unsigned int i = 0; i < 10; i++) {
+ sc.Forward();
+ }
+ sc.ForwardSetState(SCE_BAAN_DEFAULT);
+ }
+ else if (sc.MatchIgnoreCase("endfunctionusage")) {
+ for (unsigned int i = 0; i < 15; i++) {
sc.Forward();
}
sc.ForwardSetState(SCE_BAAN_DEFAULT);
}
- } else if (sc.state == SCE_BAAN_STRING) {
+ break;
+ case SCE_BAAN_STRING:
if (sc.ch == '\"') {
sc.ForwardSetState(SCE_BAAN_DEFAULT);
- } else if ((sc.atLineEnd) && (sc.chNext != '^')) {
+ }
+ else if ((sc.atLineEnd) && (sc.chNext != '^')) {
sc.ChangeState(SCE_BAAN_STRINGEOL);
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_BAAN_DEFAULT);
visibleChars = 0;
}
+ break;
}
+ // Determine if a new state should be entered.
if (sc.state == SCE_BAAN_DEFAULT) {
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
sc.SetState(SCE_BAAN_NUMBER);
- } else if (sc.MatchIgnoreCase("dllusage")){
- sc.SetState(SCE_BAAN_COMMENTDOC);
- do {
- sc.Forward();
- } while ((!sc.atLineEnd) && sc.More());
- } else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_BAAN_IDENTIFIER);
- } else if (sc.Match('|')){
- sc.SetState(SCE_BAAN_COMMENT);
- } else if (sc.ch == '\"') {
+ }
+ else if (sc.MatchIgnoreCase("dllusage") || sc.MatchIgnoreCase("functionusage")) {
+ sc.SetState(SCE_BAAN_COMMENTDOC);
+ do {
+ sc.Forward();
+ } while ((!sc.atLineEnd) && sc.More());
+ }
+ else if (IsAWordStart(sc.ch)) {
+ sc.SetState(SCE_BAAN_IDENTIFIER);
+ }
+ else if (sc.Match('|')) {
+ sc.SetState(SCE_BAAN_COMMENT);
+ }
+ else if (sc.ch == '\"' && !(lineIgnoreString)) {
sc.SetState(SCE_BAAN_STRING);
- } else if (sc.ch == '#' && visibleChars == 0) {
+ }
+ else if (sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
sc.SetState(SCE_BAAN_PREPROCESSOR);
// Skip whitespace between # and preprocessor word
do {
sc.Forward();
} while (IsASpace(sc.ch) && sc.More());
- } else if (isoperator(static_cast<char>(sc.ch))) {
+ if (sc.MatchIgnoreCase("pragma") || sc.MatchIgnoreCase("include")) {
+ lineHasPreProc = true;
+ lineIgnoreString = true;
+ }
+ else if (sc.MatchIgnoreCase("define") || sc.MatchIgnoreCase("undef")) {
+ lineHasDefines = true;
+ lineIgnoreString = false;
+ }
+ }
+ else if (IsAnOperator(static_cast<char>(sc.ch))) {
sc.SetState(SCE_BAAN_OPERATOR);
}
}
+
if (sc.atLineEnd) {
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
visibleChars = 0;
+ lineHasDomain = false;
+ lineHasFunction = false;
+ lineHasPreProc = false;
+ lineIgnoreString = false;
+ lineHasDefines = false;
}
if (!IsASpace(sc.ch)) {
visibleChars++;
@@ -137,10 +571,16 @@ static void ColouriseBaanDoc(Sci_PositionU startPos, Sci_Position length, int in
sc.Complete();
}
-static void FoldBaanDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
+
+ char word[100];
+ bool notForLoop = false;
+ int wordlen = 0;
+
+ std::string startTags[6] = { "for", "if", "on", "repeat", "select", "while" };
+ std::string endTags[6] = { "endcase", "endfor", "endif", "endselect", "endwhile", "until" };
+
+ LexAccessor styler(pAccess);
Sci_PositionU endPos = startPos + length;
int visibleChars = 0;
Sci_Position lineCurrent = styler.GetLine(startPos);
@@ -149,6 +589,7 @@ static void FoldBaanDoc(Sci_PositionU startPos, Sci_Position length, int initSty
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
+
for (Sci_PositionU i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
@@ -156,25 +597,74 @@ static void FoldBaanDoc(Sci_PositionU startPos, Sci_Position length, int initSty
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment &&
- (style == SCE_BAAN_COMMENT || style == SCE_BAAN_COMMENTDOC)) {
+ if (options.foldComment && style == SCE_BAAN_COMMENTDOC) {
if (style != stylePrev) {
levelCurrent++;
- } else if ((style != styleNext) && !atEOL) {
+ }
+ else if ((style != styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelCurrent--;
}
}
- if (style == SCE_BAAN_OPERATOR) {
- if (ch == '{') {
+ if (options.foldComment && atEOL && IsCommentLine(lineCurrent, pAccess)) {
+ if (!IsCommentLine(lineCurrent - 1, pAccess)
+ && IsCommentLine(lineCurrent + 1, pAccess))
+ levelCurrent++;
+ else if (IsCommentLine(lineCurrent - 1, pAccess)
+ && !IsCommentLine(lineCurrent + 1, pAccess))
+ levelCurrent--;
+ }
+ if (options.foldPreprocessor && atEOL && IsPreProcLine(lineCurrent, pAccess)) {
+ if (!IsPreProcLine(lineCurrent - 1, pAccess)
+ && IsPreProcLine(lineCurrent + 1, pAccess))
+ levelCurrent++;
+ else if (IsPreProcLine(lineCurrent - 1, pAccess)
+ && !IsPreProcLine(lineCurrent + 1, pAccess))
+ levelCurrent--;
+ }
+ if (options.baanFoldSyntaxBased && (style == SCE_BAAN_OPERATOR)) {
+ if (ch == '{' || ch == '(') {
levelCurrent++;
- } else if (ch == '}') {
+ }
+ else if (ch == '}' || ch == ')') {
levelCurrent--;
}
}
+ if (options.baanFoldKeywordsBased && style == SCE_BAAN_WORD) {
+ word[wordlen++] = static_cast<char>(ToLowerCase(ch));
+ if (wordlen == 100) { // prevent overflow
+ word[0] = '\0';
+ wordlen = 1;
+ }
+ if (styleNext != SCE_BAAN_WORD) {
+ word[wordlen] = '\0';
+ wordlen = 0;
+ if (strcmp(word, "for") == 0) {
+ Sci_PositionU j = i + 1;
+ while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "update")) {
+ // Means this is a "for update" used by Select which is already folded.
+ notForLoop = true;
+ }
+ }
+ else {
+ notForLoop = false;
+ }
+ if (!notForLoop) {
+ if (wordInArray(word, startTags, 6)) {
+ levelCurrent++;
+ }
+ else if (wordInArray(word, endTags, 6)) {
+ levelCurrent--;
+ }
+ }
+ }
+ }
if (atEOL) {
int lev = levelPrev;
- if (visibleChars == 0 && foldCompact)
+ if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
@@ -193,4 +683,4 @@ static void FoldBaanDoc(Sci_PositionU startPos, Sci_Position length, int initSty
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
-LexerModule lmBaan(SCLEX_BAAN, ColouriseBaanDoc, "baan", FoldBaanDoc);
+LexerModule lmBaan(SCLEX_BAAN, LexerBaan::LexerFactoryBaan, "baan", baanWordLists);