OSDN Git Service

Commit DialogBox compile Okay
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / LexProgress.cxx
diff --git a/ext/scintilla/src/LexProgress.cxx b/ext/scintilla/src/LexProgress.cxx
new file mode 100644 (file)
index 0000000..b7626e3
--- /dev/null
@@ -0,0 +1,276 @@
+// Scintilla source code edit control\r
+/** @file LexProgress.cxx\r
+ **  Lexer for Progress 4GL.\r
+ ** Based on LexCPP.cxx of Neil Hodgson <neilh@scintilla.org>\r
+  **/\r
+// Copyright 2006-2007 by Yuval Papish <Yuval@YuvCom.com>\r
+// The License.txt file describes the conditions under which this software may be distributed.\r
+\r
+/** TODO:\r
+WebSpeed support in html lexer\r
+Support "end triggers" expression of the triggers phrase\r
+change lmPS to lmProgress\r
+Support more than 6 comments levels\r
+**/\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <ctype.h>\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+\r
+#include "Platform.h"\r
+\r
+#include "PropSet.h"\r
+#include "Accessor.h"\r
+#include "StyleContext.h"\r
+#include "KeyWords.h"\r
+#include "Scintilla.h"\r
+#include "SciLexer.h"\r
+\r
+#ifdef SCI_NAMESPACE\r
+using namespace Scintilla;\r
+#endif\r
+\r
+static inline bool IsAWordChar(int ch) {\r
+       return (ch < 0x80) && (isalnum(ch) || ch == '_');\r
+}\r
+\r
+static inline bool IsAWordStart(int ch) {\r
+       return (ch < 0x80) && (isalpha(ch) || ch == '_');\r
+}\r
+\r
+enum SentenceStart { SetSentenceStart = 0xf, ResetSentenceStart = 0x10}; // true -> bit = 0\r
+\r
+static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],\r
+                            Accessor &styler) {\r
+\r
+    WordList &keywords1 = *keywordlists[0];\r
+    WordList &keywords2 = *keywordlists[1];\r
+    WordList &keywords3 = *keywordlists[2];\r
+    //WordList &keywords4 = *keywordlists[3];\r
+    //WordList &keywords5 = *keywordlists[4];\r
+\r
+       int visibleChars = 0;\r
+       int mask;\r
+\r
+       StyleContext sc(startPos, length, initStyle, styler);\r
+\r
+       for (; sc.More(); sc.Forward()) {\r
+\r
+               if (sc.atLineStart) {\r
+                       // Reset states to begining of colourise so no surprises\r
+                       // if different sets of lines lexed.\r
+                       visibleChars = 0;\r
+               }\r
+\r
+               // Handle line continuation generically.\r
+               if (sc.ch == '~') {\r
+                       if (sc.chNext > ' ') {\r
+                               // skip special char after ~\r
+                               sc.Forward();\r
+                               continue;\r
+                       }\r
+                       else {\r
+                               // Skip whitespace between ~ and EOL\r
+                               while (sc.More() && (sc.chNext == ' ' || sc.chNext == '\t') ) {\r
+                                       sc.Forward();\r
+                               }\r
+                               if (sc.chNext == '\n' || sc.chNext == '\r') {\r
+                                       sc.Forward();\r
+                                       if (sc.ch == '\r' && sc.chNext == '\n') {\r
+                                               sc.Forward();\r
+                                       }\r
+                                       sc.Forward();\r
+                                       continue;\r
+                               }\r
+                       }\r
+               }\r
+               // Determine if a new state should be terminated.\r
+               mask = sc.state & 0x10;\r
+               switch (sc.state & 0xf) {\r
+                       case SCE_4GL_OPERATOR:\r
+                               sc.SetState(SCE_4GL_DEFAULT | mask);\r
+                               break;\r
+                       case SCE_4GL_NUMBER:\r
+                               if (!(IsADigit(sc.ch))) {\r
+                                       sc.SetState(SCE_4GL_DEFAULT | mask);\r
+                               }\r
+                               break;\r
+                       case SCE_4GL_IDENTIFIER:\r
+                               if (!IsAWordChar(sc.ch) && sc.ch != '-') {\r
+                                       char s[1000];\r
+                                       sc.GetCurrentLowered(s, sizeof(s));\r
+                                       if (((sc.state & 0x10) == 0) && keywords2.InList(s) || keywords3.InList(s)) {\r
+                                               sc.ChangeState(SCE_4GL_BLOCK | ResetSentenceStart);\r
+                                       }\r
+                                       else if (keywords1.InList(s)) {\r
+                                               if ((s[0] == 'e' && s[1] =='n' && s[2] == 'd' && !isalnum(s[3]) && s[3] != '-') ||\r
+                                                       (s[0] == 'f' && s[1] =='o' && s[2] == 'r' && s[3] == 'w' && s[4] =='a' && s[5] == 'r' && s[6] == 'd'&& !isalnum(s[7]))) {\r
+                                                       sc.ChangeState(SCE_4GL_END | ResetSentenceStart);\r
+                                               }\r
+                                               else if ((s[0] == 'e' && s[1] =='l' && s[2] == 's' && s[3] == 'e') ||\r
+                                                                (s[0] == 't' && s[1] =='h' && s[2] == 'e' && s[3] == 'n')) {\r
+                                                       sc.ChangeState(SCE_4GL_WORD & SetSentenceStart);\r
+                                               }\r
+                                               else {\r
+                                                       sc.ChangeState(SCE_4GL_WORD | ResetSentenceStart);\r
+                                               }\r
+                                       }\r
+                                       sc.SetState(SCE_4GL_DEFAULT | (sc.state & 0x10));\r
+                               }\r
+                               break;\r
+                       case SCE_4GL_PREPROCESSOR:\r
+                               if (sc.atLineStart) {\r
+                                       sc.SetState(SCE_4GL_DEFAULT & SetSentenceStart);\r
+                               } else if (sc.ch == '*' && sc.chNext == '/') {\r
+                                       sc.ForwardSetState(SCE_4GL_DEFAULT | mask);\r
+                               }\r
+                               break;\r
+                       case SCE_4GL_STRING:\r
+                               if (sc.ch == '\"') {\r
+                                       sc.ForwardSetState(SCE_4GL_DEFAULT | mask);\r
+                               }\r
+                               break;\r
+                       case SCE_4GL_CHARACTER:\r
+                               if (sc.ch == '\'') {\r
+                                       sc.ForwardSetState(SCE_4GL_DEFAULT | mask);\r
+                               }\r
+                               break;\r
+                       default:\r
+                               if ((sc.state & 0xf) >= SCE_4GL_COMMENT1) {\r
+                                       if (sc.ch == '*' && sc.chNext == '/') {\r
+                                               sc.Forward();\r
+                                               if ((sc.state & 0xf) == SCE_4GL_COMMENT1) {\r
+                                                       sc.ForwardSetState(SCE_4GL_DEFAULT | mask);\r
+                                               }\r
+                                               else\r
+                                                       sc.SetState((sc.state & 0x1f) - 1);\r
+                                       } else if (sc.ch == '/' && sc.chNext == '*') {\r
+                                               sc.Forward();\r
+                                               sc.SetState((sc.state & 0x1f) + 1);\r
+                                       }\r
+                               }\r
+               }\r
+\r
+               // Determine if a new state should be entered.\r
+               mask = sc.state & 0x10;\r
+               if ((sc.state & 0xf) == SCE_4GL_DEFAULT) {\r
+                       if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {\r
+                               sc.SetState(SCE_4GL_NUMBER | ResetSentenceStart);\r
+                       } else if (IsAWordStart(sc.ch) || (sc.ch == '@')) {\r
+                               sc.SetState(SCE_4GL_IDENTIFIER | mask);\r
+                       } else if (sc.ch == '/' && sc.chNext == '*') {\r
+                               sc.SetState(SCE_4GL_COMMENT1 | mask);\r
+                               sc.Forward();\r
+                       } else if (sc.ch == '\"') {\r
+                               sc.SetState(SCE_4GL_STRING | ResetSentenceStart);\r
+                       } else if (sc.ch == '\'') {\r
+                               sc.SetState(SCE_4GL_CHARACTER | ResetSentenceStart);\r
+                       } else if (sc.ch == '&' && visibleChars == 0 && ((sc.state & 0x10) == 0)) {\r
+                               sc.SetState(SCE_4GL_PREPROCESSOR | ResetSentenceStart);\r
+                               // Skip whitespace between & and preprocessor word\r
+                               do {\r
+                                       sc.Forward();\r
+                               } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());\r
+                       // Handle syntactical line termination\r
+                       } else if ((sc.ch == '.' || sc.ch == ':' || sc.ch == '}') && (sc.chNext == ' ' || sc.chNext == '\t' || sc.chNext == '\n' || sc.chNext == '\r')) {\r
+                               sc.SetState(sc.state & SetSentenceStart);\r
+                       } else if (isoperator(static_cast<char>(sc.ch))) {\r
+                               if (sc.ch == ':')\r
+                                       sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);\r
+                               else\r
+                                       sc.SetState(SCE_4GL_OPERATOR | ResetSentenceStart);\r
+                       }\r
+               }\r
+\r
+               if (!IsASpace(sc.ch)) {\r
+                       visibleChars++;\r
+               }\r
+       }\r
+       sc.Complete();\r
+}\r
+\r
+static bool IsStreamCommentStyle(int style) {\r
+       return (style & 0xf) >= SCE_4GL_COMMENT1 ;\r
+}\r
+\r
+// Store both the current line's fold level and the next lines in the\r
+// level store to make it easy to pick up with each increment\r
+// and to make it possible to fiddle the current level for "} else {".\r
+static void FoldNoBox4glDoc(unsigned int startPos, int length, int initStyle,\r
+                            Accessor &styler) {\r
+       bool foldComment = styler.GetPropertyInt("fold.comment") != 0;\r
+       bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;\r
+       bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;\r
+       unsigned int endPos = startPos + length;\r
+       int visibleChars = 0;\r
+       int lineCurrent = styler.GetLine(startPos);\r
+       int levelCurrent = SC_FOLDLEVELBASE;\r
+       if (lineCurrent > 0)\r
+               levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;\r
+       int levelMinCurrent = levelCurrent;\r
+       int levelNext = levelCurrent;\r
+       char chNext = static_cast<char>(tolower(styler[startPos]));\r
+       int styleNext = styler.StyleAt(startPos);\r
+       int style = initStyle;\r
+       for (unsigned int i = startPos; i < endPos; i++) {\r
+               char ch = chNext;\r
+               chNext = static_cast<char>(tolower(styler.SafeGetCharAt(i + 1)));\r
+               int stylePrev = style;\r
+               style = styleNext;\r
+               styleNext = styler.StyleAt(i + 1);\r
+               bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');\r
+               if (foldComment && IsStreamCommentStyle(style)) {\r
+                       if (!IsStreamCommentStyle(stylePrev)) {\r
+                               levelNext++;\r
+                       } else if (!IsStreamCommentStyle(styleNext)) { // && !atEOL) {\r
+                               // Comments don't end at end of line and the next character may be unstyled.\r
+                               levelNext--;\r
+                       }\r
+               }\r
+               else if ((style & 0xf) == SCE_4GL_BLOCK && !isalnum(chNext)) {\r
+                       levelNext++;\r
+               }\r
+               else if ((style & 0xf) == SCE_4GL_END  && (ch == 'e' || ch == 'f')) {\r
+                       levelNext--;\r
+               }\r
+               if (atEOL) {\r
+                       int levelUse = levelCurrent;\r
+                       if (foldAtElse) {\r
+                               levelUse = levelMinCurrent;\r
+                       }\r
+                       int lev = levelUse | levelNext << 16;\r
+                       if (visibleChars == 0 && foldCompact)\r
+                               lev |= SC_FOLDLEVELWHITEFLAG;\r
+                       if (levelUse < levelNext)\r
+                               lev |= SC_FOLDLEVELHEADERFLAG;\r
+                       if (lev != styler.LevelAt(lineCurrent)) {\r
+                               styler.SetLevel(lineCurrent, lev);\r
+                       }\r
+                       lineCurrent++;\r
+                       levelCurrent = levelNext;\r
+                       levelMinCurrent = levelCurrent;\r
+                       visibleChars = 0;\r
+               }\r
+               if (!isspacechar(ch))\r
+                       visibleChars++;\r
+       }\r
+}\r
+\r
+static void Fold4glDoc(unsigned int startPos, int length, int initStyle, WordList *[],\r
+                       Accessor &styler) {\r
+       FoldNoBox4glDoc(startPos, length, initStyle, styler);\r
+}\r
+\r
+static const char * const FglWordLists[] = {\r
+            "Primary keywords and identifiers",\r
+            "Secondary keywords and identifiers",\r
+            "Documentation comment keywords",\r
+            "Unused",\r
+            "Global classes and typedefs",\r
+            0,\r
+        };\r
+\r
+LexerModule lmProgress(SCLEX_PS, Colourise4glDoc, "progress", Fold4glDoc, FglWordLists);\r
+\r
+\r