OSDN Git Service

Enable X64 Build
[tortoisegit/TortoiseGitJp.git] / ext / scintilla / src / LexInno.cxx
1 // Scintilla source code edit control\r
2 /** @file LexInno.cxx\r
3  ** Lexer for Inno Setup scripts.\r
4  **/\r
5 // Written by Friedrich Vedder <fvedd@t-online.de>, using code from LexOthers.cxx.\r
6 // The License.txt file describes the conditions under which this software may be distributed.\r
7 \r
8 #include <stdlib.h>\r
9 #include <string.h>\r
10 #include <ctype.h>\r
11 #include <stdio.h>\r
12 #include <stdarg.h>\r
13 \r
14 #include "Platform.h"\r
15 \r
16 #include "PropSet.h"\r
17 #include "Accessor.h"\r
18 #include "StyleContext.h"\r
19 #include "KeyWords.h"\r
20 #include "Scintilla.h"\r
21 #include "SciLexer.h"\r
22 \r
23 #ifdef SCI_NAMESPACE\r
24 using namespace Scintilla;\r
25 #endif\r
26 \r
27 static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler) {\r
28         int state = SCE_INNO_DEFAULT;\r
29         char chPrev;\r
30         char ch = 0;\r
31         char chNext = styler[startPos];\r
32         int lengthDoc = startPos + length;\r
33         char *buffer = new char[length];\r
34         int bufferCount = 0;\r
35         bool isBOL, isEOL, isWS, isBOLWS = 0;\r
36 \r
37         WordList &sectionKeywords = *keywordLists[0];\r
38         WordList &standardKeywords = *keywordLists[1];\r
39         WordList &parameterKeywords = *keywordLists[2];\r
40         WordList &preprocessorKeywords = *keywordLists[3];\r
41         WordList &pascalKeywords = *keywordLists[4];\r
42         WordList &userKeywords = *keywordLists[5];\r
43 \r
44         // Go through all provided text segment\r
45         // using the hand-written state machine shown below\r
46         styler.StartAt(startPos);\r
47         styler.StartSegment(startPos);\r
48         for (int i = startPos; i < lengthDoc; i++) {\r
49                 chPrev = ch;\r
50                 ch = chNext;\r
51                 chNext = styler.SafeGetCharAt(i + 1);\r
52 \r
53                 if (styler.IsLeadByte(ch)) {\r
54                         chNext = styler.SafeGetCharAt(i + 2);\r
55                         i++;\r
56                         continue;\r
57                 }\r
58 \r
59                 isBOL = (chPrev == 0) || (chPrev == '\n') || (chPrev == '\r' && ch != '\n');\r
60                 isBOLWS = (isBOL) ? 1 : (isBOLWS && (chPrev == ' ' || chPrev == '\t'));\r
61                 isEOL = (ch == '\n' || ch == '\r');\r
62                 isWS = (ch == ' ' || ch == '\t');\r
63 \r
64                 switch(state) {\r
65                         case SCE_INNO_DEFAULT:\r
66                                 if (ch == ';' && isBOLWS) {\r
67                                         // Start of a comment\r
68                                         state = SCE_INNO_COMMENT;\r
69                                 } else if (ch == '[' && isBOLWS) {\r
70                                         // Start of a section name\r
71                                         bufferCount = 0;\r
72                                         state = SCE_INNO_SECTION;\r
73                                 } else if (ch == '#' && isBOLWS) {\r
74                                         // Start of a preprocessor directive\r
75                                         state = SCE_INNO_PREPROC;\r
76                                 } else if (ch == '{' && chNext == '#') {\r
77                                         // Start of a preprocessor inline directive\r
78                                         state = SCE_INNO_PREPROC_INLINE;\r
79                                 } else if ((ch == '{' && (chNext == ' ' || chNext == '\t'))\r
80                                            || (ch == '(' && chNext == '*')) {\r
81                                         // Start of a Pascal comment\r
82                                         state = SCE_INNO_COMMENT_PASCAL;\r
83                                 } else if (ch == '"') {\r
84                                         // Start of a double-quote string\r
85                                         state = SCE_INNO_STRING_DOUBLE;\r
86                                 } else if (ch == '\'') {\r
87                                         // Start of a single-quote string\r
88                                         state = SCE_INNO_STRING_SINGLE;\r
89                                 } else if (isascii(ch) && (isalpha(ch) || (ch == '_'))) {\r
90                                         // Start of an identifier\r
91                                         bufferCount = 0;\r
92                                         buffer[bufferCount++] = static_cast<char>(tolower(ch));\r
93                                         state = SCE_INNO_IDENTIFIER;\r
94                                 } else {\r
95                                         // Style it the default style\r
96                                         styler.ColourTo(i,SCE_INNO_DEFAULT);\r
97                                 }\r
98                                 break;\r
99 \r
100                         case SCE_INNO_COMMENT:\r
101                                 if (isEOL) {\r
102                                         state = SCE_INNO_DEFAULT;\r
103                                         styler.ColourTo(i,SCE_INNO_COMMENT);\r
104                                 }\r
105                                 break;\r
106 \r
107                         case SCE_INNO_IDENTIFIER:\r
108                                 if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {\r
109                                         buffer[bufferCount++] = static_cast<char>(tolower(ch));\r
110                                 } else {\r
111                                         state = SCE_INNO_DEFAULT;\r
112                                         buffer[bufferCount] = '\0';\r
113 \r
114                                         // Check if the buffer contains a keyword\r
115                                         if (standardKeywords.InList(buffer)) {\r
116                                                 styler.ColourTo(i-1,SCE_INNO_KEYWORD);\r
117                                         } else if (parameterKeywords.InList(buffer)) {\r
118                                                 styler.ColourTo(i-1,SCE_INNO_PARAMETER);\r
119                                         } else if (pascalKeywords.InList(buffer)) {\r
120                                                 styler.ColourTo(i-1,SCE_INNO_KEYWORD_PASCAL);\r
121                                         } else if (userKeywords.InList(buffer)) {\r
122                                                 styler.ColourTo(i-1,SCE_INNO_KEYWORD_USER);\r
123                                         } else {\r
124                                                 styler.ColourTo(i-1,SCE_INNO_DEFAULT);\r
125                                         }\r
126 \r
127                                         // Push back the faulty character\r
128                                         chNext = styler[i--];\r
129                                         ch = chPrev;\r
130                                 }\r
131                                 break;\r
132 \r
133                         case SCE_INNO_SECTION:\r
134                                 if (ch == ']') {\r
135                                         state = SCE_INNO_DEFAULT;\r
136                                         buffer[bufferCount] = '\0';\r
137 \r
138                                         // Check if the buffer contains a section name\r
139                                         if (sectionKeywords.InList(buffer)) {\r
140                                                 styler.ColourTo(i,SCE_INNO_SECTION);\r
141                                         } else {\r
142                                                 styler.ColourTo(i,SCE_INNO_DEFAULT);\r
143                                         }\r
144                                 } else if (isascii(ch) && (isalnum(ch) || (ch == '_'))) {\r
145                                         buffer[bufferCount++] = static_cast<char>(tolower(ch));\r
146                                 } else {\r
147                                         state = SCE_INNO_DEFAULT;\r
148                                         styler.ColourTo(i,SCE_INNO_DEFAULT);\r
149                                 }\r
150                                 break;\r
151 \r
152                         case SCE_INNO_PREPROC:\r
153                                 if (isWS || isEOL) {\r
154                                         if (isascii(chPrev) && isalpha(chPrev)) {\r
155                                                 state = SCE_INNO_DEFAULT;\r
156                                                 buffer[bufferCount] = '\0';\r
157 \r
158                                                 // Check if the buffer contains a preprocessor directive\r
159                                                 if (preprocessorKeywords.InList(buffer)) {\r
160                                                         styler.ColourTo(i-1,SCE_INNO_PREPROC);\r
161                                                 } else {\r
162                                                         styler.ColourTo(i-1,SCE_INNO_DEFAULT);\r
163                                                 }\r
164 \r
165                                                 // Push back the faulty character\r
166                                                 chNext = styler[i--];\r
167                                                 ch = chPrev;\r
168                                         }\r
169                                 } else if (isascii(ch) && isalpha(ch)) {\r
170                                         if (chPrev == '#' || chPrev == ' ' || chPrev == '\t')\r
171                                                 bufferCount = 0;\r
172                                         buffer[bufferCount++] = static_cast<char>(tolower(ch));\r
173                                 }\r
174                                 break;\r
175 \r
176                         case SCE_INNO_STRING_DOUBLE:\r
177                                 if (ch == '"' || isEOL) {\r
178                                         state = SCE_INNO_DEFAULT;\r
179                                         styler.ColourTo(i,SCE_INNO_STRING_DOUBLE);\r
180                                 }\r
181                                 break;\r
182 \r
183                         case SCE_INNO_STRING_SINGLE:\r
184                                 if (ch == '\'' || isEOL) {\r
185                                         state = SCE_INNO_DEFAULT;\r
186                                         styler.ColourTo(i,SCE_INNO_STRING_SINGLE);\r
187                                 }\r
188                                 break;\r
189 \r
190                         case SCE_INNO_PREPROC_INLINE:\r
191                                 if (ch == '}') {\r
192                                         state = SCE_INNO_DEFAULT;\r
193                                         styler.ColourTo(i,SCE_INNO_PREPROC_INLINE);\r
194                                 } else if (isEOL) {\r
195                                         state = SCE_INNO_DEFAULT;\r
196                                         styler.ColourTo(i,SCE_INNO_DEFAULT);\r
197                                 }\r
198                                 break;\r
199 \r
200                         case SCE_INNO_COMMENT_PASCAL:\r
201                                 if (ch == '}' || (ch == ')' && chPrev == '*')) {\r
202                                         state = SCE_INNO_DEFAULT;\r
203                                         styler.ColourTo(i,SCE_INNO_COMMENT_PASCAL);\r
204                                 } else if (isEOL) {\r
205                                         state = SCE_INNO_DEFAULT;\r
206                                         styler.ColourTo(i,SCE_INNO_DEFAULT);\r
207                                 }\r
208                                 break;\r
209 \r
210                 }\r
211         }\r
212         delete []buffer;\r
213 }\r
214 \r
215 static const char * const innoWordListDesc[] = {\r
216         "Sections",\r
217         "Keywords",\r
218         "Parameters",\r
219         "Preprocessor directives",\r
220         "Pascal keywords",\r
221         "User defined keywords",\r
222         0\r
223 };\r
224 \r
225 static void FoldInnoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {\r
226         unsigned int endPos = startPos + length;\r
227         char chNext = styler[startPos];\r
228 \r
229         int lineCurrent = styler.GetLine(startPos);\r
230 \r
231         bool sectionFlag = false;\r
232         int levelPrev = lineCurrent > 0 ? styler.LevelAt(lineCurrent - 1) : SC_FOLDLEVELBASE;\r
233         int level;\r
234 \r
235         for (unsigned int i = startPos; i < endPos; i++) {\r
236                 char ch = chNext;\r
237                 chNext = styler[i+1];\r
238                 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');\r
239                 int style = styler.StyleAt(i);\r
240 \r
241                 if (style == SCE_INNO_SECTION)\r
242                         sectionFlag = true;\r
243 \r
244                 if (atEOL || i == endPos - 1) {\r
245                         if (sectionFlag) {\r
246                                 level = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;\r
247                                 if (level == levelPrev)\r
248                                         styler.SetLevel(lineCurrent - 1, levelPrev & ~SC_FOLDLEVELHEADERFLAG);\r
249                         } else {\r
250                                 level = levelPrev & SC_FOLDLEVELNUMBERMASK;\r
251                                 if (levelPrev & SC_FOLDLEVELHEADERFLAG)\r
252                                         level++;\r
253                         }\r
254 \r
255                         styler.SetLevel(lineCurrent, level);\r
256 \r
257                         levelPrev = level;\r
258                         lineCurrent++;\r
259                         sectionFlag = false;\r
260                 }\r
261         }\r
262 }\r
263 \r
264 LexerModule lmInno(SCLEX_INNOSETUP, ColouriseInnoDoc, "inno", FoldInnoDoc, innoWordListDesc);\r