123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967 |
- // Scintilla source code edit control
- /** @file LexBaan.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>
- // 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 "StyleContext.h"
- #include "CharacterSet.h"
- #include "LexerModule.h"
- #include "OptionSet.h"
- # ifdef SCI_NAMESPACE
- using namespace Scintilla;
- # 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 baanFoldSections;
- bool baanFoldInnerLevel;
- bool baanStylingWithinPreprocessor;
- OptionsBaan() {
- fold = false;
- foldComment = false;
- foldPreprocessor = false;
- foldCompact = false;
- baanFoldSyntaxBased = false;
- baanFoldKeywordsBased = false;
- baanFoldSections = false;
- baanFoldInnerLevel = 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."
- "Also folds declarations which are grouped together.");
- DefineProperty("fold.baan.sections", &OptionsBaan::baanFoldSections,
- "Set this property to 0 to disable folding of Main Sections as well as Sub Sections.");
- DefineProperty("fold.baan.inner.level", &OptionsBaan::baanFoldInnerLevel,
- "Set this property to 1 to enable folding of inner levels of select statements."
- "Disabled by default. case and if statements are also eligible" );
- 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 == '$');
- }
- 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 bool IsCommentLine(Sci_Position line, LexAccessor &styler) {
- 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];
- int style = styler.StyleAt(i);
- if (ch == '|' && style == SCE_BAAN_COMMENT)
- return true;
- else if (!IsASpaceOrTab(ch))
- return false;
- }
- return false;
- }
- static bool IsPreProcLine(Sci_Position line, LexAccessor &styler) {
- 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];
- int style = styler.StyleAt(i);
- if (ch == '#' && style == SCE_BAAN_PREPROCESSOR) {
- if (styler.Match(i, "#elif") || styler.Match(i, "#else") || styler.Match(i, "#endif")
- || styler.Match(i, "#if") || styler.Match(i, "#ifdef") || styler.Match(i, "#ifndef"))
- // Above PreProcessors has a seperate fold mechanism.
- return false;
- else
- return true;
- }
- else if (ch == '^')
- return true;
- else if (!IsASpaceOrTab(ch))
- return false;
- }
- return false;
- }
- static int mainOrSubSectionLine(Sci_Position line, LexAccessor &styler) {
- 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];
- int style = styler.StyleAt(i);
- if (style == SCE_BAAN_WORD5 || style == SCE_BAAN_WORD4)
- return style;
- else if (IsASpaceOrTab(ch))
- continue;
- else
- break;
- }
- return 0;
- }
- static bool priorSectionIsSubSection(Sci_Position line, LexAccessor &styler){
- while (line > 0) {
- 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];
- int style = styler.StyleAt(i);
- if (style == SCE_BAAN_WORD4)
- return true;
- else if (style == SCE_BAAN_WORD5)
- return false;
- else if (IsASpaceOrTab(ch))
- continue;
- else
- break;
- }
- line--;
- }
- return false;
- }
- static bool nextSectionIsSubSection(Sci_Position line, LexAccessor &styler) {
- while (line > 0) {
- 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];
- int style = styler.StyleAt(i);
- if (style == SCE_BAAN_WORD4)
- return true;
- else if (style == SCE_BAAN_WORD5)
- return false;
- else if (IsASpaceOrTab(ch))
- continue;
- else
- break;
- }
- line++;
- }
- return false;
- }
- static bool IsDeclarationLine(Sci_Position line, LexAccessor &styler) {
- 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];
- int style = styler.StyleAt(i);
- if (style == SCE_BAAN_WORD) {
- if (styler.Match(i, "table") || styler.Match(i, "extern") || styler.Match(i, "long")
- || styler.Match(i, "double") || styler.Match(i, "boolean") || styler.Match(i, "string")
- || styler.Match(i, "domain")) {
- for (Sci_Position j = eol_pos; j > pos; j--) {
- int styleFromEnd = styler.StyleAt(j);
- if (styleFromEnd == SCE_BAAN_COMMENT)
- continue;
- else if (IsASpace(styler[j]))
- continue;
- else if (styler[j] != ',')
- //Above conditions ensures, Declaration is not part of any function parameters.
- return true;
- else
- return false;
- }
- }
- else
- return false;
- }
- else if (!IsASpaceOrTab(ch))
- return false;
- }
- return false;
- }
- static bool IsInnerLevelFold(Sci_Position line, LexAccessor &styler) {
- 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];
- int style = styler.StyleAt(i);
- if (style == SCE_BAAN_WORD && (styler.Match(i, "else" ) || styler.Match(i, "case")
- || styler.Match(i, "default") || styler.Match(i, "selectdo") || styler.Match(i, "selecteos")
- || styler.Match(i, "selectempty") || styler.Match(i, "selecterror")))
- return true;
- else if (IsASpaceOrTab(ch))
- continue;
- else
- return false;
- }
- return false;
- }
- 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);
- }
- Sci_Position SCI_METHOD PropertySet(const char *key, const char *val);
- const char * SCI_METHOD DescribeWordListSets() {
- return osBaan.DescribeWordListSets();
- }
- 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;
- char word[1000];
- int wordlen = 0;
- std::string preProcessorTags[11] = { "#define", "#elif", "#else", "#endif",
- "#ident", "#if", "#ifdef", "#ifndef",
- "#include", "#pragma", "#undef" };
- LexAccessor styler(pAccess);
- StyleContext sc(startPos, length, initStyle, styler);
- for (; sc.More(); sc.Forward()) {
- // Determine if the current state should terminate.
- switch (sc.state) {
- case SCE_BAAN_OPERATOR:
- sc.SetState(SCE_BAAN_DEFAULT);
- break;
- case SCE_BAAN_NUMBER:
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- break;
- case SCE_BAAN_IDENTIFIER:
- if (!IsAWordChar(sc.ch)) {
- char s[1000];
- char s1[1000];
- sc.GetCurrentLowered(s, sizeof(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);
- if (0 == strcmp(s, "domain")) {
- lineHasDomain = true;
- }
- else if (0 == strcmp(s, "function")) {
- lineHasFunction = true;
- }
- }
- else if (lineHasDomain) {
- sc.ChangeState(SCE_BAAN_DOMDEF);
- lineHasDomain = false;
- }
- else if (lineHasFunction) {
- sc.ChangeState(SCE_BAAN_FUNCDEF);
- lineHasFunction = false;
- }
- 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 (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);
- }
- break;
- case SCE_BAAN_PREPROCESSOR:
- if (options.baanStylingWithinPreprocessor) {
- if (IsASpace(sc.ch) || IsAnOperator(sc.ch)) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- }
- else {
- if (sc.atLineEnd && (sc.chNext != '^')) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- }
- break;
- case SCE_BAAN_COMMENT:
- if (sc.atLineEnd) {
- sc.SetState(SCE_BAAN_DEFAULT);
- }
- break;
- case SCE_BAAN_COMMENTDOC:
- if (sc.MatchIgnoreCase("enddllusage")) {
- 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);
- }
- break;
- case SCE_BAAN_STRING:
- if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_BAAN_DEFAULT);
- }
- else if ((sc.atLineEnd) && (sc.chNext != '^')) {
- sc.ChangeState(SCE_BAAN_STRINGEOL);
- 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.MatchIgnoreCase("functionusage")) {
- sc.SetState(SCE_BAAN_COMMENTDOC);
- do {
- sc.Forward();
- } while ((!sc.atLineEnd) && sc.More());
- }
- else if (iswordstart(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) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_BAAN_PREPROCESSOR);
- word[0] = '\0';
- wordlen = 0;
- while (sc.More() && !(IsASpace(sc.chNext) || IsAnOperator(sc.chNext))) {
- sc.Forward();
- wordlen++;
- }
- sc.GetCurrentLowered(word, sizeof(word));
- if (!sc.atLineEnd) {
- word[wordlen++] = sc.ch;
- word[wordlen++] = '\0';
- }
- if (!wordInArray(word, preProcessorTags, 11))
- // Colorise only preprocessor built in Baan.
- sc.ChangeState(SCE_BAAN_IDENTIFIER);
- if (strcmp(word, "#pragma") == 0 || strcmp(word, "#include") == 0) {
- lineHasPreProc = true;
- lineIgnoreString = true;
- }
- else if (strcmp(word, "#define") == 0 || strcmp(word, "#undef") == 0 ||
- strcmp(word, "#ifdef") == 0 || strcmp(word, "#if") == 0 || strcmp(word, "#ifndef") == 0) {
- 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++;
- }
- }
- sc.Complete();
- }
- void SCI_METHOD LexerBaan::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
- if (!options.fold)
- return;
- char word[100];
- int wordlen = 0;
- bool foldStart = true;
- bool foldNextSelect = true;
- bool afterFunctionSection = false;
- bool beforeDeclarationSection = false;
- int currLineStyle = 0;
- int nextLineStyle = 0;
- std::string startTags[6] = { "for", "if", "on", "repeat", "select", "while" };
- std::string endTags[6] = { "endcase", "endfor", "endif", "endselect", "endwhile", "until" };
- std::string selectCloseTags[5] = { "selectdo", "selecteos", "selectempty", "selecterror", "endselect" };
- LexAccessor styler(pAccess);
- Sci_PositionU endPos = startPos + length;
- int visibleChars = 0;
- Sci_Position lineCurrent = styler.GetLine(startPos);
- // Backtrack to previous line in case need to fix its fold status
- if (startPos > 0) {
- if (lineCurrent > 0) {
- lineCurrent--;
- startPos = styler.LineStart(lineCurrent);
- }
- }
- int levelPrev = SC_FOLDLEVELBASE;
- if (lineCurrent > 0)
- levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
- int levelCurrent = levelPrev;
- char chNext = styler[startPos];
- int style = initStyle;
- int styleNext = styler.StyleAt(startPos);
- for (Sci_PositionU i = startPos; i < endPos; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
- style = styleNext;
- styleNext = styler.StyleAt(i + 1);
- int stylePrev = (i) ? styler.StyleAt(i - 1) : SCE_BAAN_DEFAULT;
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- // Comment folding
- if (options.foldComment && style == SCE_BAAN_COMMENTDOC) {
- if (style != stylePrev) {
- levelCurrent++;
- }
- else if (style != styleNext) {
- levelCurrent--;
- }
- }
- if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
- if (!IsCommentLine(lineCurrent - 1, styler)
- && IsCommentLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsCommentLine(lineCurrent - 1, styler)
- && !IsCommentLine(lineCurrent + 1, styler))
- levelCurrent--;
- }
- // PreProcessor Folding
- if (options.foldPreprocessor) {
- if (atEOL && IsPreProcLine(lineCurrent, styler)) {
- if (!IsPreProcLine(lineCurrent - 1, styler)
- && IsPreProcLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsPreProcLine(lineCurrent - 1, styler)
- && !IsPreProcLine(lineCurrent + 1, styler))
- levelCurrent--;
- }
- else if (style == SCE_BAAN_PREPROCESSOR) {
- // folds #ifdef/#if/#ifndef - they are not part of the IsPreProcLine folding.
- if (ch == '#') {
- if (styler.Match(i, "#ifdef") || styler.Match(i, "#if") || styler.Match(i, "#ifndef"))
- levelCurrent++;
- else if (styler.Match(i, "#endif"))
- levelCurrent--;
- }
- }
- }
- //Syntax Folding
- if (options.baanFoldSyntaxBased && (style == SCE_BAAN_OPERATOR)) {
- if (ch == '{' || ch == '(') {
- levelCurrent++;
- }
- else if (ch == '}' || ch == ')') {
- levelCurrent--;
- }
- }
- //Keywords Folding
- if (options.baanFoldKeywordsBased) {
- if (atEOL && IsDeclarationLine(lineCurrent, styler)) {
- if (!IsDeclarationLine(lineCurrent - 1, styler)
- && IsDeclarationLine(lineCurrent + 1, styler))
- levelCurrent++;
- else if (IsDeclarationLine(lineCurrent - 1, styler)
- && !IsDeclarationLine(lineCurrent + 1, styler))
- levelCurrent--;
- }
- else if (style == SCE_BAAN_WORD) {
- word[wordlen++] = static_cast<char>(MakeLowerCase(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.
- foldStart = false;
- }
- }
- else if (strcmp(word, "on") == 0) {
- Sci_PositionU j = i + 1;
- while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
- j++;
- }
- if (!styler.Match(j, "case")) {
- // Means this is not a "on Case" statement... could be "on" used by index.
- foldStart = false;
- }
- }
- else if (strcmp(word, "select") == 0) {
- if (foldNextSelect) {
- // Next Selects are sub-clause till reach of selectCloseTags[] array.
- foldNextSelect = false;
- foldStart = true;
- }
- else {
- foldNextSelect = false;
- foldStart = false;
- }
- }
- else if (wordInArray(word, selectCloseTags, 5)) {
- // select clause ends, next select clause can be folded.
- foldNextSelect = true;
- foldStart = true;
- }
- else {
- foldStart = true;
- }
- if (foldStart) {
- if (wordInArray(word, startTags, 6)) {
- levelCurrent++;
- }
- else if (wordInArray(word, endTags, 6)) {
- levelCurrent--;
- }
- }
- }
- }
- }
- // Fold inner level of if/select/case statements
- if (options.baanFoldInnerLevel && atEOL) {
- bool currLineInnerLevel = IsInnerLevelFold(lineCurrent, styler);
- bool nextLineInnerLevel = IsInnerLevelFold(lineCurrent + 1, styler);
- if (currLineInnerLevel && currLineInnerLevel != nextLineInnerLevel) {
- levelCurrent++;
- }
- else if (nextLineInnerLevel && nextLineInnerLevel != currLineInnerLevel) {
- levelCurrent--;
- }
- }
- // Section Foldings.
- // One way of implementing Section Foldings, as there is no END markings of sections.
- // first section ends on the previous line of next section.
- // Re-written whole folding to accomodate this.
- if (options.baanFoldSections && atEOL) {
- currLineStyle = mainOrSubSectionLine(lineCurrent, styler);
- nextLineStyle = mainOrSubSectionLine(lineCurrent + 1, styler);
- if (currLineStyle != 0 && currLineStyle != nextLineStyle) {
- if (levelCurrent < levelPrev)
- --levelPrev;
- for (Sci_Position j = styler.LineStart(lineCurrent); j < styler.LineStart(lineCurrent + 1) - 1; j++) {
- if (IsASpaceOrTab(styler[j]))
- continue;
- else if (styler.StyleAt(j) == SCE_BAAN_WORD5) {
- if (styler.Match(j, "functions:")) {
- // Means functions: is the end of MainSections.
- // Nothing to fold after this.
- afterFunctionSection = true;
- break;
- }
- else {
- afterFunctionSection = false;
- break;
- }
- }
- else {
- afterFunctionSection = false;
- break;
- }
- }
- if (!afterFunctionSection)
- levelCurrent++;
- }
- else if (nextLineStyle != 0 && currLineStyle != nextLineStyle
- && (priorSectionIsSubSection(lineCurrent -1 ,styler)
- || !nextSectionIsSubSection(lineCurrent + 1, styler))) {
- for (Sci_Position j = styler.LineStart(lineCurrent + 1); j < styler.LineStart(lineCurrent + 1 + 1) - 1; j++) {
- if (IsASpaceOrTab(styler[j]))
- continue;
- else if (styler.StyleAt(j) == SCE_BAAN_WORD5) {
- if (styler.Match(j, "declaration:")) {
- // Means declaration: is the start of MainSections.
- // Nothing to fold before this.
- beforeDeclarationSection = true;
- break;
- }
- else {
- beforeDeclarationSection = false;
- break;
- }
- }
- else {
- beforeDeclarationSection = false;
- break;
- }
- }
- if (!beforeDeclarationSection) {
- levelCurrent--;
- if (nextLineStyle == SCE_BAAN_WORD5 && priorSectionIsSubSection(lineCurrent-1, styler))
- // next levelCurrent--; is to unfold previous subsection fold.
- // On reaching the next main section, the previous main as well sub section ends.
- levelCurrent--;
- }
- }
- }
- if (atEOL) {
- int lev = levelPrev;
- lev |= levelCurrent << 16;
- if (visibleChars == 0 && options.foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if ((levelCurrent > levelPrev) && (visibleChars > 0))
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent)) {
- styler.SetLevel(lineCurrent, lev);
- }
- lineCurrent++;
- levelPrev = levelCurrent;
- visibleChars = 0;
- }
- if (!isspacechar(ch))
- visibleChars++;
- }
- int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
- styler.SetLevel(lineCurrent, levelPrev | flagsNext);
- }
- LexerModule lmBaan(SCLEX_BAAN, LexerBaan::LexerFactoryBaan, "baan", baanWordLists);
|