OSDN Git Service

WIP: Add syntax highlighter for AutoIt
[winmerge-jp/winmerge-jp.git] / Externals / crystaledit / editlib / parsers / autoit.cpp
1 ///////////////////////////////////////////////////////////////////////////
2 //  File:    autoit.cpp
3 //  Version: 1.1.0.4
4 //  Updated: 19-Jul-1998
5 //
6 //  Copyright:  Ferdinand Prantl, portions by Stcherbatchenko Andrei
7 //  E-mail:     prantl@ff.cuni.cz
8 //
9 //  AutoIt syntax highlighing definition
10 //
11 //  You are free to use or modify this code to the following restrictions:
12 //  - Acknowledge me somewhere in your about box, simple "Parts of code by.."
13 //  will be enough. If you can't (or don't want to), contact me personally.
14 //  - LEAVE THIS HEADER INTACT
15 ////////////////////////////////////////////////////////////////////////////
16
17 #include "StdAfx.h"
18 #include "crystallineparser.h"
19 #include "../SyntaxColors.h"
20 #include "../utils/string_util.h"
21
22 #ifdef _DEBUG
23 #define new DEBUG_NEW
24 #endif
25
26 //  (Visual) AutoIt keywords
27 static const TCHAR * s_apszAutoItKeywordList[] =
28   {
29     _T ("Abs"),
30     _T ("AddHandler"),
31     _T ("AddressOf"),
32     _T ("Alias"),
33     _T ("And"),
34     _T ("AndAlso"),
35     _T ("Ansi"),
36     _T ("Any"),
37     _T ("AppActivate"),
38     _T ("As"),
39     _T ("Asc"),
40     _T ("Assembly"),
41     _T ("Atn"),
42     _T ("Attribute"),
43     _T ("Auto"),
44     _T ("Base"),
45     _T ("Beep"),
46     _T ("Begin"),
47     _T ("BeginProperty"),
48     _T ("Binary"),
49     _T ("Boolean"),
50     _T ("ByRef"),
51     _T ("Byte"),
52     _T ("ByVal"),
53     _T ("Call"),
54     _T ("Case"),
55     _T ("Catch"),
56     _T ("CBool"),
57     _T ("CByte"),
58     _T ("CChar"),
59     _T ("CDate"),
60     _T ("CDbl"),
61     _T ("CDec"),
62     _T ("Char"),
63     _T ("ChDir"),
64     _T ("ChDrive"),
65     _T ("CheckBox"),
66     _T ("Chr"),
67     _T ("CInt"),
68     _T ("Class"),
69     _T ("CLng"),
70     _T ("Close"),
71     _T ("CObj"),
72     _T ("Compare"),
73     _T ("Const"),
74     _T ("Continue"),
75     _T ("Cos"),
76     _T ("CreateObject"),
77     _T ("CreateVerifyItem"),
78     _T ("CSByte"),
79     _T ("CShort"),
80     _T ("CSng"),
81     _T ("CStr"),
82     _T ("CType"),
83     _T ("CUInt"),
84     _T ("CULng"),
85     _T ("CurDir"),
86     _T ("Currency"),
87     _T ("CUShort"),
88     _T ("Custom"),
89     _T ("CVar"),
90     _T ("Database"),
91     _T ("Date"),
92     _T ("Decimal"),
93     _T ("Declare"),
94     _T ("Default"),
95     _T ("Delegate"),
96     _T ("Dialog"),
97     _T ("Dim"),
98     _T ("Dir"),
99     _T ("DirectCast"),
100     _T ("DlgEnable"),
101     _T ("DlgText"),
102     _T ("DlgVisible"),
103     _T ("Do"),
104     _T ("Double"),
105     _T ("Each"),
106     _T ("Else"),
107     _T ("ElseIf"),
108     _T ("End"),
109     _T ("EndIf"),
110     _T ("EndProperty"),
111     _T ("Enum"),
112     _T ("EOF"),
113     _T ("Erase"),
114     _T ("Error"),
115     _T ("Event"),
116     _T ("Exit"),
117     _T ("Exp"),
118     _T ("Explicit"),
119     _T ("ExternalSource"),
120     _T ("False"),
121     _T ("FileCopy"),
122     _T ("FileLen"),
123     _T ("Finally"),
124     _T ("Fix"),
125     _T ("For"),
126     _T ("Format"),
127     _T ("Friend"),
128     _T ("Function"),
129     _T ("Get"),
130     _T ("GetAttrName"),
131     _T ("GetAttrType"),
132     _T ("GetAttrValBool"),
133     _T ("GetAttrValEnumInt"),
134     _T ("GetAttrValEnumString"),
135     _T ("GetAttrValFloat"),
136     _T ("GetAttrValInt"),
137     _T ("GetAttrValString"),
138     _T ("GetClassId"),
139     _T ("GetGeoType"),
140     _T ("GetObject"),
141     _T ("GetType"),
142     _T ("Global"),
143     _T ("GoSub"),
144     _T ("GoTo"),
145     _T ("Handles"),
146     _T ("Hex"),
147     _T ("Hour"),
148     _T ("If"),
149     _T ("Implements"),
150     _T ("Imports"),
151     _T ("Inherits"),
152     _T ("Input"),
153     _T ("Input#"),
154     _T ("InputBox"),
155     _T ("InStr"),
156     _T ("Int"),
157     _T ("Integer"),
158     _T ("Interface"),
159     _T ("Is"),
160     _T ("IsDate"),
161     _T ("IsEmpty"),
162     _T ("IsFalse"),
163     _T ("IsNot"),
164     _T ("IsNull"),
165     _T ("IsNumeric"),
166     _T ("IsTrue"),
167     _T ("Kill"),
168     _T ("LBound"),
169     _T ("LCase"),
170     _T ("Left"),
171     _T ("Len"),
172     _T ("Let"),
173     _T ("Lib"),
174     _T ("Like"),
175     _T ("Like"),
176     _T ("Line"),
177     _T ("Log"),
178     _T ("Long"),
179     _T ("Loop"),
180     _T ("LTrim"),
181     _T ("Me"),
182     _T ("Mid"),
183     _T ("Minute"),
184     _T ("MkDir"),
185     _T ("Mod"),
186     _T ("Module"),
187     _T ("Month"),
188     _T ("MsgBox"),
189     _T ("MustInherit"),
190     _T ("MustOverride"),
191     _T ("My"),
192     _T ("MyBase"),
193     _T ("MyClass"),
194     _T ("Name"),
195     _T ("Namespace"),
196     _T ("Narrowing"),
197     _T ("New"),
198     _T ("Next"),
199     _T ("Not"),
200     _T ("Nothing"),
201     _T ("NotInheritable"),
202     _T ("NotOverridable"),
203     _T ("Now"),
204     _T ("Object"),
205     _T ("Oct"),
206     _T ("Of"),
207     _T ("Off"),
208     _T ("On"),
209     _T ("Open"),
210     _T ("Operator"),
211     _T ("Option"),
212     _T ("Optional"),
213     _T ("Or"),
214     _T ("OrElse"),
215     _T ("Overloads"),
216     _T ("Overridable"),
217     _T ("Overrides"),
218     _T ("ParamArray"),
219     _T ("Partial"),
220     _T ("Preserve"),
221     _T ("Print"),
222     _T ("Private"),
223     _T ("Property"),
224     _T ("Protected"),
225     _T ("Public"),
226     _T ("RaiseEvent"),
227     _T ("ReadOnly"),
228     _T ("ReDim"),
229     _T ("Region"),
230     _T ("Rem"),
231     _T ("RemoveHandler"),
232     _T ("Resume"),
233     _T ("Return"),
234     _T ("Right"),
235     _T ("RmDir"),
236     _T ("Rnd"),
237     _T ("RTrim"),
238     _T ("Sbyte"),
239     _T ("Second"),
240     _T ("Seek"),
241     _T ("Select"),
242     _T ("SendKeys"),
243     _T ("Set"),
244     _T ("SetAttrValBool"),
245     _T ("SetAttrValEnumInt"),
246     _T ("SetAttrValEnumString"),
247     _T ("SetAttrValFloat"),
248     _T ("SetAttrValInt"),
249     _T ("SetAttrValString"),
250     _T ("Shadows"),
251     _T ("Shared"),
252     _T ("Shell"),
253     _T ("Short"),
254     _T ("Sin"),
255     _T ("Single"),
256     _T ("SMDoMenu"),
257     _T ("Space"),
258     _T ("Sqr"),
259     _T ("Static"),
260     _T ("Step"),
261     _T ("Stop"),
262     _T ("Str"),
263     _T ("StrComp"),
264     _T ("Strict"),
265     _T ("String"),
266     _T ("StringFunction"),
267     _T ("Structure"),
268     _T ("Sub"),
269     _T ("SyncLock"),
270     _T ("Tan"),
271     _T ("Text"),
272     _T ("TextBox"),
273     _T ("Then"),
274     _T ("Throw"),
275     _T ("Time"),
276     _T ("TimeSerial"),
277     _T ("TimeValue"),
278     _T ("To"),
279     _T ("Trim"),
280     _T ("True"),
281     _T ("Try"),
282     _T ("TryCast"),
283     _T ("Type"),
284     _T ("TypeOf"),
285     _T ("UBound"),
286     _T ("UCase"),
287     _T ("UInteger"),
288     _T ("ULong"),
289     _T ("Unicode"),
290     _T ("Until"),
291     _T ("UShort"),
292     _T ("Using"),
293     _T ("Val"),
294     _T ("Variant"),
295     _T ("VarType"),
296     _T ("VerifyCardinalities"),
297     _T ("Version"),
298     _T ("Wend"),
299     _T ("When"),
300     _T ("While"),
301     _T ("Widening"),
302     _T ("With"),
303     _T ("WithEvents"),
304     _T ("Write"),
305     _T ("WriteOnly"),
306     _T ("Xor"),
307     _T ("Year"),
308   };
309
310 static bool
311 IsAutoItKeyword (const TCHAR *pszChars, int nLength)
312 {
313   return ISXKEYWORDI (s_apszAutoItKeywordList, pszChars, nLength);
314 }
315
316 inline void
317 DefineIdentiferBlock(const TCHAR *pszChars, int nLength, CrystalLineParser::TEXTBLOCK * pBuf, int &nActualItems, int nIdentBegin, int I)
318 {
319   if (IsAutoItKeyword (pszChars + nIdentBegin, I - nIdentBegin))
320     {
321       DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
322     }
323   else if (CrystalLineParser::IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
324     {
325       DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
326     }
327   else
328     {
329       bool bFunction = false;
330
331       for (int j = I; j < nLength; j++)
332         {
333           if (!xisspace (pszChars[j]))
334             {
335               if (pszChars[j] == '(')
336                 {
337                   bFunction = true;
338                 }
339               break;
340             }
341         }
342       if (bFunction)
343         {
344           DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
345         }
346     }
347 }
348
349 unsigned
350 CrystalLineParser::ParseLineAutoIt (unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
351 {
352   if (nLength == 0)
353     return dwCookie & COOKIE_EXT_COMMENT;
354
355   bool bRedefineBlock = true;
356   bool bDecIndex = false;
357   int nIdentBegin = -1;
358   int nPrevI = -1;
359   int I=0;
360   for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
361     {
362       if (I == nPrevI)
363         {
364           // CharNext did not advance, so we're at the end of the string
365           // and we already handled this character, so stop
366           break;
367         }
368
369       if (bRedefineBlock)
370         {
371           int nPos = I;
372           if (bDecIndex)
373             nPos = nPrevI;
374           if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
375             {
376               DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
377             }
378           else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
379             {
380               DEFINE_BLOCK (nPos, COLORINDEX_STRING);
381             }
382           else
383             {
384               if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos))))
385                 {
386                   DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
387                 }
388               else
389                 {
390                   DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
391                   bRedefineBlock = true;
392                   bDecIndex = true;
393                   goto out;
394                 }
395             }
396           bRedefineBlock = false;
397           bDecIndex = false;
398         }
399 out:
400
401       // Can be bigger than length if there is binary data
402       // See bug #1474782 Crash when comparing SQL with with binary data
403       if (I >= nLength || pszChars[I] == 0)
404         break;
405
406       if (dwCookie & COOKIE_COMMENT)
407         {
408           DEFINE_BLOCK (I, COLORINDEX_COMMENT);
409           dwCookie |= COOKIE_COMMENT;
410           break;
411         }
412
413       //  String constant "...."
414       if (dwCookie & COOKIE_STRING)
415         {
416           if (pszChars[I] == '"')
417             {
418               dwCookie &= ~COOKIE_STRING;
419               bRedefineBlock = true;
420             }
421           continue;
422         }
423
424       if (pszChars[I] == '\'')
425         {
426           if (nIdentBegin >= 0)
427             DefineIdentiferBlock(pszChars, nLength, pBuf, nActualItems, nIdentBegin, I);
428           DEFINE_BLOCK (I, COLORINDEX_COMMENT);
429           dwCookie |= COOKIE_COMMENT;
430           break;
431         }
432
433       //  Normal text
434       if (pszChars[I] == '"')
435         {
436           DEFINE_BLOCK (I, COLORINDEX_STRING);
437           dwCookie |= COOKIE_STRING;
438           continue;
439         }
440
441       if (pBuf == nullptr)
442         continue;               //  We don't need to extract keywords,
443       //  for faster parsing skip the rest of loop
444
445       if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1])))
446         {
447           if (nIdentBegin == -1)
448             nIdentBegin = I;
449         }
450       else
451         {
452           if (nIdentBegin >= 0)
453             {
454               DefineIdentiferBlock(pszChars, nLength, pBuf, nActualItems, nIdentBegin, I);
455               bRedefineBlock = true;
456               bDecIndex = true;
457               nIdentBegin = -1;
458             }
459         }
460     }
461
462   if (nIdentBegin >= 0)
463     DefineIdentiferBlock(pszChars, nLength, pBuf, nActualItems, nIdentBegin, I);
464
465   dwCookie &= COOKIE_EXT_COMMENT;
466   return dwCookie;
467 }