OSDN Git Service

Merge X64 Build
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / LexGui4Cli.cxx
1 // Scintilla source code edit control\r
2 // Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>\r
3 /*\r
4 This is the Lexer for Gui4Cli, included in SciLexer.dll\r
5 - by d. Keletsekis, 2/10/2003\r
6 \r
7 To add to SciLexer.dll:\r
8 1. Add the values below to INCLUDE\Scintilla.iface\r
9 2. Run the include/HFacer.py script\r
10 3. Run the src/lexGen.py script\r
11 \r
12 val SCE_GC_DEFAULT=0\r
13 val SCE_GC_COMMENTLINE=1\r
14 val SCE_GC_COMMENTBLOCK=2\r
15 val SCE_GC_GLOBAL=3\r
16 val SCE_GC_EVENT=4\r
17 val SCE_GC_ATTRIBUTE=5\r
18 val SCE_GC_CONTROL=6\r
19 val SCE_GC_COMMAND=7\r
20 val SCE_GC_STRING=8\r
21 val SCE_GC_OPERATOR=9\r
22 */\r
23 \r
24 #include <stdlib.h>\r
25 #include <string.h>\r
26 #include <ctype.h>\r
27 #include <stdio.h>\r
28 #include <stdarg.h>\r
29 \r
30 #include "Platform.h"\r
31 \r
32 #include "PropSet.h"\r
33 #include "Accessor.h"\r
34 #include "StyleContext.h"\r
35 #include "KeyWords.h"\r
36 #include "Scintilla.h"\r
37 #include "SciLexer.h"\r
38 \r
39 #ifdef SCI_NAMESPACE\r
40 using namespace Scintilla;\r
41 #endif\r
42 \r
43 #define debug Platform::DebugPrintf\r
44 \r
45 static inline bool IsAWordChar(const int ch) {\r
46         return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch =='\\');\r
47 }\r
48 \r
49 static inline bool IsAWordStart(const int ch) {\r
50         return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');\r
51 }\r
52 \r
53 inline bool isGCOperator(int ch)\r
54 {       if (isalnum(ch))\r
55                 return false;\r
56         // '.' left out as it is used to make up numbers\r
57         if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||\r
58                  ch == '(' || ch == ')' || ch == '=' || ch == '%' ||\r
59                  ch == '[' || ch == ']' || ch == '<' || ch == '>' ||\r
60                  ch == ',' || ch == ';' || ch == ':')\r
61                 return true;\r
62         return false;\r
63 }\r
64 \r
65 #define isSpace(x)              ((x)==' ' || (x)=='\t')\r
66 #define isNL(x)                 ((x)=='\n' || (x)=='\r')\r
67 #define isSpaceOrNL(x)  (isSpace(x) || isNL(x))\r
68 #define BUFFSIZE 500\r
69 #define isFoldPoint(x)  ((styler.LevelAt(x) & SC_FOLDLEVELNUMBERMASK) == 1024)\r
70 \r
71 static void colorFirstWord(WordList *keywordlists[], Accessor &styler,\r
72                                                                         StyleContext *sc, char *buff, int length, int)\r
73 {\r
74         int c = 0;\r
75         while (sc->More() && isSpaceOrNL(sc->ch))\r
76         {       sc->Forward();\r
77         }\r
78         styler.ColourTo(sc->currentPos - 1, sc->state);\r
79 \r
80         if (!IsAWordChar(sc->ch)) // comment, marker, etc..\r
81                 return;\r
82 \r
83         while (sc->More() && !isSpaceOrNL(sc->ch) && (c < length-1) && !isGCOperator(sc->ch))\r
84         {       buff[c] = static_cast<char>(sc->ch);\r
85                 ++c; sc->Forward();\r
86         }\r
87         buff[c] = '\0';\r
88         char *p = buff;\r
89         while (*p)      // capitalize..\r
90         {       if (islower(*p)) *p = static_cast<char>(toupper(*p));\r
91                 ++p;\r
92         }\r
93 \r
94         WordList &kGlobal               = *keywordlists[0];     // keyword lists set by the user\r
95         WordList &kEvent                = *keywordlists[1];\r
96         WordList &kAttribute    = *keywordlists[2];\r
97         WordList &kControl      = *keywordlists[3];\r
98         WordList &kCommand      = *keywordlists[4];\r
99 \r
100         int state = 0;\r
101         // int level = styler.LevelAt(line) & SC_FOLDLEVELNUMBERMASK;\r
102         // debug ("line = %d, level = %d", line, level);\r
103 \r
104         if           (kGlobal.InList(buff))             state = SCE_GC_GLOBAL;\r
105         else if (kAttribute.InList(buff))       state = SCE_GC_ATTRIBUTE;\r
106         else if (kControl.InList(buff))         state = SCE_GC_CONTROL;\r
107         else if (kCommand.InList(buff))         state = SCE_GC_COMMAND;\r
108         else if (kEvent.InList(buff))                   state = SCE_GC_EVENT;\r
109 \r
110         if (state)\r
111         {       sc->ChangeState(state);\r
112                 styler.ColourTo(sc->currentPos - 1, sc->state);\r
113                 sc->ChangeState(SCE_GC_DEFAULT);\r
114         }\r
115         else\r
116         {       sc->ChangeState(SCE_GC_DEFAULT);\r
117                 styler.ColourTo(sc->currentPos - 1, sc->state);\r
118         }\r
119 }\r
120 \r
121 // Main colorizing function called by Scintilla\r
122 static void\r
123 ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle,\r
124                     WordList *keywordlists[], Accessor &styler)\r
125 {\r
126         styler.StartAt(startPos);\r
127 \r
128         int quotestart = 0, oldstate, currentline = styler.GetLine(startPos);\r
129         styler.StartSegment(startPos);\r
130         bool noforward;\r
131         char buff[BUFFSIZE+1];  // buffer for command name\r
132 \r
133         StyleContext sc(startPos, length, initStyle, styler);\r
134         buff[0] = '\0'; // cbuff = 0;\r
135 \r
136         if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..\r
137                 colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);\r
138 \r
139         while (sc.More())\r
140         {       noforward = 0;\r
141 \r
142                 switch (sc.ch)\r
143                 {\r
144                         case '/':\r
145                                 if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)\r
146                                         break;\r
147                                 if (sc.chNext == '/')   // line comment\r
148                                 {       sc.SetState (SCE_GC_COMMENTLINE);\r
149                                         sc.Forward();\r
150                                         styler.ColourTo(sc.currentPos, sc.state);\r
151                                 }\r
152                                 else if (sc.chNext == '*')      // block comment\r
153                                 {       sc.SetState(SCE_GC_COMMENTBLOCK);\r
154                                         sc.Forward();\r
155                                         styler.ColourTo(sc.currentPos, sc.state);\r
156                                 }\r
157                                 else\r
158                                         styler.ColourTo(sc.currentPos, sc.state);\r
159                                 break;\r
160 \r
161                         case '*':       // end of comment block, or operator..\r
162                                 if (sc.state == SCE_GC_STRING)\r
163                                         break;\r
164                                 if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')\r
165                                 {       sc.Forward();\r
166                                         styler.ColourTo(sc.currentPos, sc.state);\r
167                                         sc.ChangeState (SCE_GC_DEFAULT);\r
168                                 }\r
169                                 else\r
170                                         styler.ColourTo(sc.currentPos, sc.state);\r
171                                 break;\r
172 \r
173                         case '\'':      case '\"': // strings..\r
174                                 if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)\r
175                                         break;\r
176                                 if (sc.state == SCE_GC_STRING)\r
177                                 {       if (sc.ch == quotestart)        // match same quote char..\r
178                                         {       styler.ColourTo(sc.currentPos, sc.state);\r
179                                                 sc.ChangeState(SCE_GC_DEFAULT);\r
180                                                 quotestart = 0;\r
181                                 }       }\r
182                                 else\r
183                                 {       styler.ColourTo(sc.currentPos - 1, sc.state);\r
184                                         sc.ChangeState(SCE_GC_STRING);\r
185                                         quotestart = sc.ch;\r
186                                 }\r
187                                 break;\r
188 \r
189                         case ';':       // end of commandline character\r
190                                 if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&\r
191                                          sc.state != SCE_GC_STRING)\r
192                                 {\r
193                                         styler.ColourTo(sc.currentPos - 1, sc.state);\r
194                                         styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);\r
195                                         sc.ChangeState(SCE_GC_DEFAULT);\r
196                                         sc.Forward();\r
197                                         colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);\r
198                                         noforward = 1; // don't move forward - already positioned at next char..\r
199                                 }\r
200                                 break;\r
201 \r
202                         case '+': case '-': case '=':   case '!':       // operators..\r
203                         case '<': case '>': case '&': case '|': case '$':\r
204                                 if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&\r
205                                          sc.state != SCE_GC_STRING)\r
206                                 {\r
207                                         styler.ColourTo(sc.currentPos - 1, sc.state);\r
208                                         styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);\r
209                                         sc.ChangeState(SCE_GC_DEFAULT);\r
210                                 }\r
211                                 break;\r
212 \r
213                         case '\\':      // escape - same as operator, but also mark in strings..\r
214                                 if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)\r
215                                 {\r
216                                         oldstate = sc.state;\r
217                                         styler.ColourTo(sc.currentPos - 1, sc.state);\r
218                                         sc.Forward(); // mark also the next char..\r
219                                         styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);\r
220                                         sc.ChangeState(oldstate);\r
221                                 }\r
222                                 break;\r
223 \r
224                         case '\n': case '\r':\r
225                                 ++currentline;\r
226                                 if (sc.state == SCE_GC_COMMENTLINE)\r
227                                 {       styler.ColourTo(sc.currentPos, sc.state);\r
228                                         sc.ChangeState (SCE_GC_DEFAULT);\r
229                                 }\r
230                                 else if (sc.state != SCE_GC_COMMENTBLOCK)\r
231                                 {       colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);\r
232                                         noforward = 1; // don't move forward - already positioned at next char..\r
233                                 }\r
234                                 break;\r
235 \r
236 //                      case ' ': case '\t':\r
237 //                      default :\r
238                 }\r
239 \r
240                 if (!noforward) sc.Forward();\r
241 \r
242         }\r
243         sc.Complete();\r
244 }\r
245 \r
246 // Main folding function called by Scintilla - (based on props (.ini) files function)\r
247 static void FoldGui4Cli(unsigned int startPos, int length, int,\r
248                                                                 WordList *[], Accessor &styler)\r
249 {\r
250         bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;\r
251 \r
252         unsigned int endPos = startPos + length;\r
253         int visibleChars = 0;\r
254         int lineCurrent = styler.GetLine(startPos);\r
255 \r
256         char chNext = styler[startPos];\r
257         int styleNext = styler.StyleAt(startPos);\r
258         bool headerPoint = false;\r
259 \r
260         for (unsigned int i = startPos; i < endPos; i++)\r
261         {\r
262                 char ch = chNext;\r
263                 chNext = styler[i+1];\r
264 \r
265                 int style = styleNext;\r
266                 styleNext = styler.StyleAt(i + 1);\r
267                 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');\r
268 \r
269                 if (style == SCE_GC_EVENT || style == SCE_GC_GLOBAL)\r
270                 {       headerPoint = true; // fold at events and globals\r
271                 }\r
272 \r
273                 if (atEOL)\r
274                 {       int lev = SC_FOLDLEVELBASE+1;\r
275 \r
276                         if (headerPoint)\r
277                                 lev = SC_FOLDLEVELBASE;\r
278 \r
279                         if (visibleChars == 0 && foldCompact)\r
280                                 lev |= SC_FOLDLEVELWHITEFLAG;\r
281 \r
282                         if (headerPoint)\r
283                                 lev |= SC_FOLDLEVELHEADERFLAG;\r
284 \r
285                         if (lev != styler.LevelAt(lineCurrent)) // set level, if not already correct\r
286                         {       styler.SetLevel(lineCurrent, lev);\r
287                         }\r
288 \r
289                         lineCurrent++;          // re-initialize our flags\r
290                         visibleChars = 0;\r
291                         headerPoint = false;\r
292                 }\r
293 \r
294                 if (!(isspacechar(ch))) // || (style == SCE_GC_COMMENTLINE) || (style != SCE_GC_COMMENTBLOCK)))\r
295                         visibleChars++;\r
296         }\r
297 \r
298         int lev = headerPoint ? SC_FOLDLEVELBASE : SC_FOLDLEVELBASE+1;\r
299         int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;\r
300         styler.SetLevel(lineCurrent, lev | flagsNext);\r
301 }\r
302 \r
303 // I have no idea what these are for.. probably accessible by some message.\r
304 static const char * const gui4cliWordListDesc[] = {\r
305         "Globals", "Events", "Attributes", "Control", "Commands",\r
306         0\r
307 };\r
308 \r
309 // Declare language & pass our function pointers to Scintilla\r
310 LexerModule lmGui4Cli(SCLEX_GUI4CLI, ColouriseGui4CliDoc, "gui4cli", FoldGui4Cli, gui4cliWordListDesc);\r
311 \r
312 #undef debug\r
313 \r