From 6dc13618762576ea94f64226e91c69e6a1a3bec4 Mon Sep 17 00:00:00 2001 From: nyamatongwe Date: Tue, 14 Oct 2003 10:16:08 +0000 Subject: Patch from Chuanjian Shen: 1.) "forall" and "where" statement folding bug. 2.) simple folding with "do label" structure. 3.) label colourise bug. 4.) number colourise bug (such as 1.D0) --- src/LexFortran.cxx | 356 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 247 insertions(+), 109 deletions(-) (limited to 'src') diff --git a/src/LexFortran.cxx b/src/LexFortran.cxx index e2109a0ab..72de3193a 100644 --- a/src/LexFortran.cxx +++ b/src/LexFortran.cxx @@ -1,51 +1,63 @@ // Scintilla source code edit control /** @file LexFortran.cxx ** Lexer for Fortran. - ** Writen by Chuan-jian Shen, Last changed Nov. 2002 + ** Writen by Chuan-jian Shen, Last changed Sep. 2003 **/ // Copyright 1998-2001 by Neil Hodgson // The License.txt file describes the conditions under which this software may be distributed. - +/***************************************/ #include #include #include #include #include - +/***************************************/ #include "Platform.h" - #include "PropSet.h" #include "Accessor.h" #include "StyleContext.h" #include "KeyWords.h" #include "Scintilla.h" #include "SciLexer.h" - +/***********************************************/ static inline bool IsAWordChar(const int ch) { return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '%'); } - +/**********************************************/ static inline bool IsAWordStart(const int ch) { return (ch < 0x80) && (isalnum(ch)); } - +/***************************************/ inline bool IsABlank(unsigned int ch) { return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ; } -static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], - Accessor &styler, bool isFixFormat) { - +/***************************************/ +inline bool IsALineEnd(char ch) { + return ((ch == '\n') || (ch == '\r')) ; +} +/***************************************/ +unsigned int GetContinuedPos(unsigned int pos, Accessor &styler) { + while (!IsALineEnd(styler.SafeGetCharAt(pos++))) continue; + if (styler.SafeGetCharAt(pos) == '\n') pos++; + while (IsABlank(styler.SafeGetCharAt(pos++))) continue; + char chCur = styler.SafeGetCharAt(pos); + if (chCur == '&') { + while (IsABlank(styler.SafeGetCharAt(++pos))) continue; + return pos; + } else { + return pos; + } +} +/***************************************/ +static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle, + WordList *keywordlists[], Accessor &styler, bool isFixFormat) { WordList &keywords = *keywordlists[0]; WordList &keywords2 = *keywordlists[1]; WordList &keywords3 = *keywordlists[2]; - - int posLineStart = 0, prevState = 0; + /***************************************/ + int posLineStart = 0, numNonBlank = 0, prevState = 0; int endPos = startPos + length; - - // backtrack to the beginning of the document, this may be slow for big documents. - // initStyle = SCE_F_DEFAULT; - // StyleContext sc(0, startPos+length, initStyle, styler); - + /***************************************/ // backtrack to the nearest keyword while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_F_WORD)) { startPos--; @@ -53,22 +65,47 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle startPos = styler.LineStart(styler.GetLine(startPos)); initStyle = styler.StyleAt(startPos - 1); StyleContext sc(startPos, endPos-startPos, initStyle, styler); - + /***************************************/ for (; sc.More(); sc.Forward()) { - - // remember the position of the line + // remember the start position of the line if (sc.atLineStart) { posLineStart = sc.currentPos; + numNonBlank = 0; sc.SetState(SCE_F_DEFAULT); } - + if (!IsASpaceOrTab(sc.ch)) numNonBlank ++; + /***********************************************/ + // Handle the fix format generically + int toLineStart = sc.currentPos - posLineStart; + if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) { + if (toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') { + sc.SetState(SCE_F_COMMENT); + while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end + } else if (toLineStart > 72) { + sc.SetState(SCE_F_COMMENT); + while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end + } else if (toLineStart < 5) { + if (IsADigit(sc.ch)) + sc.SetState(SCE_F_LABEL); + else + sc.SetState(SCE_F_DEFAULT); + } else if (toLineStart == 5) { + if (!IsASpace(sc.ch) && sc.ch != '0') { + sc.SetState(SCE_F_CONTINUATION); + sc.ForwardSetState(prevState); + } else + sc.SetState(SCE_F_DEFAULT); + } + continue; + } + /***************************************/ // Handle line continuation generically. - if (sc.ch == '&') { + if (!isFixFormat && sc.ch == '&') { char chTemp = ' '; int j = 1; while (IsABlank(chTemp) && j<132) { chTemp = static_cast(sc.GetRelative(j)); - j ++; + j++; } if (chTemp == '!') { sc.SetState(SCE_F_CONTINUATION); @@ -76,24 +113,21 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle } else if (chTemp == '\r' || chTemp == '\n') { int currentState = sc.state; sc.SetState(SCE_F_CONTINUATION); - if (currentState == SCE_F_STRING1 || currentState == SCE_F_STRING2) { - sc.ForwardSetState(SCE_F_DEFAULT); - while (IsASpace(sc.ch) && sc.More()) sc.Forward(); - if (sc.ch == '&') { - sc.SetState(SCE_F_CONTINUATION); - sc.Forward(); - } - sc.SetState(currentState); + sc.ForwardSetState(SCE_F_DEFAULT); + while (IsASpace(sc.ch) && sc.More()) sc.Forward(); + if (sc.ch == '&') { + sc.SetState(SCE_F_CONTINUATION); + sc.Forward(); } + sc.SetState(currentState); } - continue; } - + /***************************************/ // Determine if the current state should terminate. if (sc.state == SCE_F_OPERATOR) { sc.SetState(SCE_F_DEFAULT); } else if (sc.state == SCE_F_NUMBER) { - if (!IsAWordChar(sc.ch)) { + if (!(IsAWordChar(sc.ch) || sc.ch=='\'' || sc.ch=='\"' || sc.ch=='.')) { sc.SetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_IDENTIFIER) { @@ -123,24 +157,14 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle prevState = SCE_F_DEFAULT; } } else if (sc.atLineEnd) { - if (isFixFormat) { - sc.ForwardSetState(SCE_F_DEFAULT); - posLineStart = sc.currentPos; - } else { - sc.ChangeState(SCE_F_STRINGEOL); - sc.ForwardSetState(SCE_F_DEFAULT); - } + sc.ChangeState(SCE_F_STRINGEOL); + sc.ForwardSetState(SCE_F_DEFAULT); } } else if (sc.state == SCE_F_STRING2) { prevState = sc.state; if (sc.atLineEnd) { - if (isFixFormat) { - sc.ForwardSetState(SCE_F_DEFAULT); - posLineStart = sc.currentPos; - } else { - sc.ChangeState(SCE_F_STRINGEOL); - sc.ForwardSetState(SCE_F_DEFAULT); - } + sc.ChangeState(SCE_F_STRINGEOL); + sc.ForwardSetState(SCE_F_DEFAULT); } else if (sc.ch == '\"') { if (sc.chNext == '\"') { sc.Forward(); @@ -156,33 +180,32 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle } else if (sc.state == SCE_F_CONTINUATION) { sc.SetState(SCE_F_DEFAULT); } else if (sc.state == SCE_F_LABEL) { - if (sc.currentPos >= static_cast(posLineStart+5)) { + if (!IsADigit(sc.ch)) { sc.SetState(SCE_F_DEFAULT); + } else { + if (isFixFormat && sc.currentPos-posLineStart > 4) + sc.SetState(SCE_F_DEFAULT); + else if (numNonBlank > 5) + sc.SetState(SCE_F_DEFAULT); } } - + /***************************************/ // Determine if a new state should be entered. if (sc.state == SCE_F_DEFAULT) { - int toLineStart = sc.currentPos - posLineStart; - if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) { - if (sc.atLineStart && (tolower(sc.ch) == 'c' || sc.ch == '*') || sc.ch == '!') { - sc.SetState(SCE_F_COMMENT); - } else if (toLineStart > 72) { - sc.SetState(SCE_F_COMMENT); - } else if (toLineStart < 5 && !IsASpace(sc.ch)) { - sc.SetState(SCE_F_LABEL); - } else if (toLineStart == 5 && (!IsASpace(sc.ch) && sc.ch != '0')) { - sc.SetState(SCE_F_CONTINUATION); - sc.ForwardSetState(prevState); - } + if (sc.ch == '!') { + sc.SetState(SCE_F_COMMENT); + } else if ((!isFixFormat) && IsADigit(sc.ch) && numNonBlank == 1) { + sc.SetState(SCE_F_LABEL); } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { sc.SetState(SCE_F_NUMBER); + } else if ((tolower(sc.ch) == 'b' || tolower(sc.ch) == 'o' || + tolower(sc.ch) == 'z') && (sc.chNext == '\"' || sc.chNext == '\'')) { + sc.SetState(SCE_F_NUMBER); + sc.Forward(); } else if (sc.ch == '.' && isalpha(sc.chNext)) { sc.SetState(SCE_F_OPERATOR2); } else if (IsAWordStart(sc.ch)) { sc.SetState(SCE_F_IDENTIFIER); - } else if (sc.ch == '!') { - sc.SetState(SCE_F_COMMENT); } else if (sc.ch == '\"') { sc.SetState(SCE_F_STRING2); } else if (sc.ch == '\'') { @@ -194,37 +217,46 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle } sc.Complete(); } - -// The folding depends on the mercy of the programer. -static int classifyFoldPointFortran(const char* s, const char* prevWord) { +/***************************************/ +// To determine the folding level depending on keywords +static int classifyFoldPointFortran(const char* s, const char* prevWord, const char chNextNonBlank) { int lev = 0; - if (strcmp(prevWord, "end") == 0) return lev; if ((strcmp(prevWord, "else") == 0 && strcmp(s, "if") == 0) || strcmp(s, "elseif") == 0) return -1; if (strcmp(s, "associate") == 0 || strcmp(s, "block") == 0 || strcmp(s, "blockdata") == 0 || strcmp(s, "select") == 0 || strcmp(s, "do") == 0 || strcmp(s, "enum") ==0 - || strcmp(s, "forall") == 0 || strcmp(s, "function") == 0 - || strcmp(s, "interface") == 0 || strcmp(s, "module") == 0 - || strcmp(s, "program") == 0 || strcmp(s, "subroutine") == 0 - || strcmp(s, "then") == 0 || strcmp(s, "where") == 0) { - lev = 1; - } else if (strcmp(s, "end") == 0 || strcmp(s, "continue") == 0 - || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0 - || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0 - || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0 - || strcmp(s, "endif") == 0 - || strcmp(s, "endforall") == 0 || strcmp(s, "endfunction") == 0 - || strcmp(s, "endinterface") == 0 || strcmp(s, "endmodule") == 0 - || strcmp(s, "endprogram") == 0 || strcmp(s, "endsubroutine") == 0 - || strcmp(s, "endwhere") == 0 || strcmp(s, "procedure") == 0 ) { - lev = -1; + || strcmp(s, "function") == 0 || strcmp(s, "interface") == 0 + || strcmp(s, "module") == 0 || strcmp(s, "program") == 0 + || strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0 + || (strcmp(s, "type") == 0 && chNextNonBlank != '(') ){ + if (strcmp(prevWord, "end") == 0) + lev = 0; + else + lev = 1; + } else if (strcmp(s, "end") == 0 && chNextNonBlank != '=' + || strcmp(s, "endassociate") == 0 || strcmp(s, "endblock") == 0 + || strcmp(s, "endblockdata") == 0 || strcmp(s, "endselect") == 0 + || strcmp(s, "enddo") == 0 || strcmp(s, "endenum") ==0 + || strcmp(s, "endif") == 0 || strcmp(s, "endforall") == 0 + || strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0 + || strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0 + || strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0 + || strcmp(s, "endwhere") == 0 + || strcmp(s, "procedure") == 0 ) { // Take care of the module procedure statement + lev = -1; + } else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if + lev = 0; } return lev; } -static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) { - //~ bool foldComment = styler.GetPropertyInt("fold.comment") != 0; +// Folding the code +static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, + Accessor &styler, bool isFixFormat) { + // + // bool foldComment = styler.GetPropertyInt("fold.comment") != 0; // Do not know how to fold the comment at the moment. + // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; unsigned int endPos = startPos + length; int visibleChars = 0; @@ -232,37 +264,135 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, Wor int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK; int levelCurrent = levelPrev; char chNext = styler[startPos]; + char chNextNonBlank; int styleNext = styler.StyleAt(startPos); int style = initStyle; - + /***************************************/ int lastStart = 0; - char prevWord[32] = ""; - + char prevWord[32] = "", Label[6] = ""; + // Variables for do label folding. + static int doLabels[100], posLabel=-1; + /***************************************/ for (unsigned int i = startPos; i < endPos; i++) { char ch = chNext; chNext = styler.SafeGetCharAt(i + 1); + chNextNonBlank = chNext; + unsigned int j=i+1; + while(IsABlank(chNextNonBlank) && j(tolower(styler[lastStart + j])); + unsigned int k; + for(k=0; (k<31 ) && (k(tolower(styler[lastStart+k])); + } + s[k] = '\0'; + // Handle the forall and where statement and structure. + if (strcmp(s, "forall") == 0 || strcmp(s, "where") == 0) { + if (strcmp(prevWord, "end") == 0) { + levelCurrent--; + } else { + j = i + 1; + char chBrace = '(', chSeek = ')', ch1 = styler.SafeGetCharAt(j); + // Find the position of the first ( + while (ch1 != chBrace && j -1) { + levelCurrent--; + posLabel--; + } + } } if (atEOL) { int lev = levelPrev; @@ -278,33 +408,41 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle, Wor visibleChars = 0; strcpy(prevWord, ""); } - - if (!isspacechar(ch)) - visibleChars++; + /***************************************/ + if (!isspacechar(ch)) visibleChars++; } - + /***************************************/ // Fill in the real level of the next line, keeping the current flags as they will be filled in later int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK; styler.SetLevel(lineCurrent, levelPrev | flagsNext); } - +/***************************************/ static const char * const FortranWordLists[] = { "Primary keywords and identifiers", "Intrinsic functions", "Extended and user defined functions", 0, }; - +/***************************************/ static void ColouriseFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, false); } - +/***************************************/ static void ColouriseFortranDocFixFormat(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler) { ColouriseFortranDoc(startPos, length, initStyle, keywordlists, styler, true); } - - -LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDoc, FortranWordLists); -LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDoc, FortranWordLists); +/***************************************/ +static void FoldFortranDocFreeFormat(unsigned int startPos, int length, int initStyle, + WordList *[], Accessor &styler) { + FoldFortranDoc(startPos, length, initStyle,styler, false); +} +/***************************************/ +static void FoldFortranDocFixFormat(unsigned int startPos, int length, int initStyle, + WordList *[], Accessor &styler) { + FoldFortranDoc(startPos, length, initStyle,styler, true); +} +/***************************************/ +LexerModule lmFortran(SCLEX_FORTRAN, ColouriseFortranDocFreeFormat, "fortran", FoldFortranDocFreeFormat, FortranWordLists); +LexerModule lmF77(SCLEX_F77, ColouriseFortranDocFixFormat, "f77", FoldFortranDocFixFormat, FortranWordLists); -- cgit v1.2.3