OSDN Git Service

ed0a9c5adbcd6c341901a94080f9200086dc11d1
[winmerge-jp/winmerge-jp.git] / Externals / crystaledit / editlib / parsers / autoit.cpp
1 ///////////////////////////////////////////////////////////////////////////
2 //  File:    autoit.cpp
3 //  Version: 1.1.0.5
4 //  Updated: 23-Apr-2021
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 ("ACos"),
31     _T ("AdlibRegister"),
32     _T ("AdlibUnRegister"),
33     _T ("And"),
34     _T ("Asc"),
35     _T ("AscW"),
36     _T ("ASin"),
37     _T ("Assign"),
38     _T ("ATan"),
39     _T ("AutoItSetOption"),
40     _T ("AutoItWinGetTitle"),
41     _T ("AutoItWinSetTitle"),
42     _T ("Beep"),
43     _T ("Binary"),
44     _T ("BinaryLen"),
45     _T ("BinaryMid"),
46     _T ("BinaryToString"),
47     _T ("BitAND"),
48     _T ("BitNOT"),
49     _T ("BitOR"),
50     _T ("BitRotate"),
51     _T ("BitShift"),
52     _T ("BitXOR"),
53     _T ("BlockInput"),
54     _T ("Break"),
55     _T ("ByRef"),
56     _T ("Call"),
57     _T ("Case"),
58     _T ("CDTray"),
59     _T ("Ceiling"),
60     _T ("Chr"),
61     _T ("ChrW"),
62     _T ("ClipGet"),
63     _T ("ClipPut"),
64     _T ("ConsoleRead"),
65     _T ("ConsoleWrite"),
66     _T ("ConsoleWriteError"),
67     _T ("Const"),
68     _T ("ContinueCase"),
69     _T ("ContinueLoop"),
70     _T ("ControlClick"),
71     _T ("ControlCommand"),
72     _T ("ControlDisable"),
73     _T ("ControlEnable"),
74     _T ("ControlFocus"),
75     _T ("ControlGetFocus"),
76     _T ("ControlGetHandle"),
77     _T ("ControlGetPos"),
78     _T ("ControlGetText"),
79     _T ("ControlHide"),
80     _T ("ControlListView"),
81     _T ("ControlMove"),
82     _T ("ControlSend"),
83     _T ("ControlSetText"),
84     _T ("ControlShow"),
85     _T ("ControlTreeView"),
86     _T ("Cos"),
87     _T ("Dec"),
88     _T ("Default"),
89     _T ("Dim"),
90     _T ("DirCopy"),
91     _T ("DirCreate"),
92     _T ("DirGetSize"),
93     _T ("DirMove"),
94     _T ("DirRemove"),
95     _T ("DllCall"),
96     _T ("DllCallAddress"),
97     _T ("DllCallbackFree"),
98     _T ("DllCallbackGetPtr"),
99     _T ("DllCallbackRegister"),
100     _T ("DllClose"),
101     _T ("DllOpen"),
102     _T ("DllStructCreate"),
103     _T ("DllStructGetData"),
104     _T ("DllStructGetPtr"),
105     _T ("DllStructGetSize"),
106     _T ("DllStructGetString"),
107     _T ("DllStructSetData"),
108     _T ("Do"),
109     _T ("DriveGetDrive"),
110     _T ("DriveGetFileSystem"),
111     _T ("DriveGetLabel"),
112     _T ("DriveGetSerial"),
113     _T ("DriveGetType"),
114     _T ("DriveMapAdd"),
115     _T ("DriveMapDel"),
116     _T ("DriveMapGet"),
117     _T ("DriveSetLabel"),
118     _T ("DriveSpaceFree"),
119     _T ("DriveSpaceTotal"),
120     _T ("DriveStatus"),
121     _T ("Else"),
122     _T ("ElseIf"),
123     _T ("EndFunc"),
124     _T ("EndIf"),
125     _T ("EndSelect"),
126     _T ("EndSwitch"),
127     _T ("EndWith"),
128     _T ("Enum"),
129     _T ("EnvGet"),
130     _T ("EnvSet"),
131     _T ("EnvUpdate"),
132     _T ("Eval"),
133     _T ("Execute"),
134     _T ("Exit"),
135     _T ("ExitLoop"),
136     _T ("Exp"),
137     _T ("False"),
138     _T ("FileChangeDir"),
139     _T ("FileClose"),
140     _T ("FileCopy"),
141     _T ("FileCreateNTFSLink"),
142     _T ("FileCreateShortcut"),
143     _T ("FileDelete"),
144     _T ("FileExists"),
145     _T ("FileFindFirstFile"),
146     _T ("FileFindNextFile"),
147     _T ("FileFlush"),
148     _T ("FileGetAttrib"),
149     _T ("FileGetEncoding"),
150     _T ("FileGetLongName"),
151     _T ("FileGetPos"),
152     _T ("FileGetShortcut"),
153     _T ("FileGetShortName"),
154     _T ("FileGetSize"),
155     _T ("FileGetTime"),
156     _T ("FileGetVersion"),
157     _T ("FileInstall"),
158     _T ("FileMove"),
159     _T ("FileOpen"),
160     _T ("FileOpenDialog"),
161     _T ("FileRead"),
162     _T ("FileReadLine"),
163     _T ("FileReadToArray"),
164     _T ("FileRecycle"),
165     _T ("FileRecycleEmpty"),
166     _T ("FileSaveDialog"),
167     _T ("FileSelectFolder"),
168     _T ("FileSetAttrib"),
169     _T ("FileSetEnd"),
170     _T ("FileSetPos"),
171     _T ("FileSetTime"),
172     _T ("FileWrite"),
173     _T ("FileWriteLine"),
174     _T ("Floor"),
175     _T ("For"),
176     _T ("FtpSetProxy"),
177     _T ("Func"),
178     _T ("FuncGetStack"),
179     _T ("FuncName"),
180     _T ("Global"),
181     _T ("GUICreate"),
182     _T ("GUICtrlCreateAvi"),
183     _T ("GUICtrlCreateButton"),
184     _T ("GUICtrlCreateCheckbox"),
185     _T ("GUICtrlCreateCombo"),
186     _T ("GUICtrlCreateContextMenu"),
187     _T ("GUICtrlCreateDate"),
188     _T ("GUICtrlCreateDummy"),
189     _T ("GUICtrlCreateEdit"),
190     _T ("GUICtrlCreateGraphic"),
191     _T ("GUICtrlCreateGroup"),
192     _T ("GUICtrlCreateIcon"),
193     _T ("GUICtrlCreateInput"),
194     _T ("GUICtrlCreateLabel"),
195     _T ("GUICtrlCreateList"),
196     _T ("GUICtrlCreateListView"),
197     _T ("GUICtrlCreateListViewItem"),
198     _T ("GUICtrlCreateMenu"),
199     _T ("GUICtrlCreateMenuItem"),
200     _T ("GUICtrlCreateMonthCal"),
201     _T ("GUICtrlCreateObj"),
202     _T ("GUICtrlCreatePic"),
203     _T ("GUICtrlCreateProgress"),
204     _T ("GUICtrlCreateRadio"),
205     _T ("GUICtrlCreateSlider"),
206     _T ("GUICtrlCreateTab"),
207     _T ("GUICtrlCreateTabItem"),
208     _T ("GUICtrlCreateTreeView"),
209     _T ("GUICtrlCreateTreeViewItem"),
210     _T ("GUICtrlCreateUpdown"),
211     _T ("GUICtrlDelete"),
212     _T ("GUICtrlGetHandle"),
213     _T ("GUICtrlGetState"),
214     _T ("GUICtrlRead"),
215     _T ("GUICtrlRecvMsg"),
216     _T ("GUICtrlRegisterListViewSort"),
217     _T ("GUICtrlSendMsg"),
218     _T ("GUICtrlSendToDummy"),
219     _T ("GUICtrlSetBkColor"),
220     _T ("GUICtrlSetColor"),
221     _T ("GUICtrlSetCursor"),
222     _T ("GUICtrlSetData"),
223     _T ("GUICtrlSetDefBkColor"),
224     _T ("GUICtrlSetDefColor"),
225     _T ("GUICtrlSetFont"),
226     _T ("GUICtrlSetGraphic"),
227     _T ("GUICtrlSetImage"),
228     _T ("GUICtrlSetLimit"),
229     _T ("GUICtrlSetOnEvent"),
230     _T ("GUICtrlSetPos"),
231     _T ("GUICtrlSetResizing"),
232     _T ("GUICtrlSetState"),
233     _T ("GUICtrlSetStyle"),
234     _T ("GUICtrlSetTip"),
235     _T ("GUIDelete"),
236     _T ("GUIGetCursorInfo"),
237     _T ("GUIGetMsg"),
238     _T ("GUIGetStyle"),
239     _T ("GUIRegisterMsg"),
240     _T ("GUISetAccelerators"),
241     _T ("GUISetBkColor"),
242     _T ("GUISetCoord"),
243     _T ("GUISetCursor"),
244     _T ("GUISetFont"),
245     _T ("GUISetHelp"),
246     _T ("GUISetIcon"),
247     _T ("GUISetOnEvent"),
248     _T ("GUISetState"),
249     _T ("GUISetStyle"),
250     _T ("GUIStartGroup"),
251     _T ("GUISwitch"),
252     _T ("Hex"),
253     _T ("HotKeySet"),
254     _T ("HttpSetProxy"),
255     _T ("HttpSetUserAgent"),
256     _T ("HWnd"),
257     _T ("If"),
258     _T ("In"),
259     _T ("InetClose"),
260     _T ("InetGet"),
261     _T ("InetGetInfo"),
262     _T ("InetGetSize"),
263     _T ("InetRead"),
264     _T ("IniDelete"),
265     _T ("IniRead"),
266     _T ("IniReadSection"),
267     _T ("IniReadSectionNames"),
268     _T ("IniRenameSection"),
269     _T ("IniWrite"),
270     _T ("IniWriteSection"),
271     _T ("InputBox"),
272     _T ("Int"),
273     _T ("IsAdmin"),
274     _T ("IsArray"),
275     _T ("IsBinary"),
276     _T ("IsBool"),
277     _T ("IsDeclared"),
278     _T ("IsDllStruct"),
279     _T ("IsFloat"),
280     _T ("IsFunc"),
281     _T ("IsHWnd"),
282     _T ("IsInt"),
283     _T ("IsKeyword"),
284     _T ("IsMap"),
285     _T ("IsNumber"),
286     _T ("IsObj"),
287     _T ("IsPtr"),
288     _T ("IsString"),
289     _T ("Local"),
290     _T ("Log"),
291     _T ("MapAppend"),
292     _T ("MapExists"),
293     _T ("MapKeys"),
294     _T ("MapRemove"),
295     _T ("MemGetStats"),
296     _T ("Mod"),
297     _T ("MouseClick"),
298     _T ("MouseClickDrag"),
299     _T ("MouseDown"),
300     _T ("MouseGetCursor"),
301     _T ("MouseGetPos"),
302     _T ("MouseMove"),
303     _T ("MouseUp"),
304     _T ("MouseWheel"),
305     _T ("MsgBox"),
306     _T ("Next"),
307     _T ("Not"),
308     _T ("Null"),
309     _T ("Number"),
310     _T ("ObjCreate"),
311     _T ("ObjCreateInterface"),
312     _T ("ObjEvent"),
313     _T ("ObjEvent"),
314     _T ("ObjGet"),
315     _T ("ObjName"),
316     _T ("OnAutoItExitRegister"),
317     _T ("OnAutoItExitUnRegister"),
318     _T ("Opt"),
319     _T ("Or"),
320     _T ("Ping"),
321     _T ("PixelChecksum"),
322     _T ("PixelGetColor"),
323     _T ("PixelSearch"),
324     _T ("ProcessClose"),
325     _T ("ProcessExists"),
326     _T ("ProcessGetStats"),
327     _T ("ProcessList"),
328     _T ("ProcessSetPriority"),
329     _T ("ProcessWait"),
330     _T ("ProcessWaitClose"),
331     _T ("ProgressOff"),
332     _T ("ProgressOn"),
333     _T ("ProgressSet"),
334     _T ("Ptr"),
335     _T ("Random"),
336     _T ("ReDim"),
337     _T ("RegDelete"),
338     _T ("RegEnumKey"),
339     _T ("RegEnumVal"),
340     _T ("RegRead"),
341     _T ("RegWrite"),
342     _T ("Return"),
343     _T ("Round"),
344     _T ("Run"),
345     _T ("RunAs"),
346     _T ("RunAsWait"),
347     _T ("RunWait"),
348     _T ("Select"),
349     _T ("Send"),
350     _T ("SendKeepActive"),
351     _T ("SetError"),
352     _T ("SetExtended"),
353     _T ("ShellExecute"),
354     _T ("ShellExecuteWait"),
355     _T ("Shutdown"),
356     _T ("Sin"),
357     _T ("Sleep"),
358     _T ("SoundPlay"),
359     _T ("SoundSetWaveVolume"),
360     _T ("SplashImageOn"),
361     _T ("SplashOff"),
362     _T ("SplashTextOn"),
363     _T ("Sqrt"),
364     _T ("SRandom"),
365     _T ("Static"),
366     _T ("StatusbarGetText"),
367     _T ("StderrRead"),
368     _T ("StdinWrite"),
369     _T ("StdioClose"),
370     _T ("StdoutRead"),
371     _T ("Step"),
372     _T ("String"),
373     _T ("StringAddCR"),
374     _T ("StringCompare"),
375     _T ("StringFormat"),
376     _T ("StringFromASCIIArray"),
377     _T ("StringInStr"),
378     _T ("StringIsAlNum"),
379     _T ("StringIsAlpha"),
380     _T ("StringIsASCII"),
381     _T ("StringIsDigit"),
382     _T ("StringIsFloat"),
383     _T ("StringIsInt"),
384     _T ("StringIsLower"),
385     _T ("StringIsSpace"),
386     _T ("StringIsUpper"),
387     _T ("StringIsXDigit"),
388     _T ("StringLeft"),
389     _T ("StringLen"),
390     _T ("StringLower"),
391     _T ("StringMid"),
392     _T ("StringRegExp"),
393     _T ("StringRegExpReplace"),
394     _T ("StringReplace"),
395     _T ("StringReverse"),
396     _T ("StringRight"),
397     _T ("StringSplit"),
398     _T ("StringStripCR"),
399     _T ("StringStripWS"),
400     _T ("StringToASCIIArray"),
401     _T ("StringToBinary"),
402     _T ("StringTrimLeft"),
403     _T ("StringTrimRight"),
404     _T ("StringUpper"),
405     _T ("Switch"),
406     _T ("Tan"),
407     _T ("TCPAccept"),
408     _T ("TCPCloseSocket"),
409     _T ("TCPConnect"),
410     _T ("TCPListen"),
411     _T ("TCPNameToIP"),
412     _T ("TCPRecv"),
413     _T ("TCPSend"),
414     _T ("TCPShutdown"),
415     _T ("TCPShutdownSocket"),
416     _T ("TCPStartup"),
417     _T ("Then"),
418     _T ("TimerDiff"),
419     _T ("TimerInit"),
420     _T ("To"),
421     _T ("ToolTip"),
422     _T ("TrayCreateItem"),
423     _T ("TrayCreateMenu"),
424     _T ("TrayGetMsg"),
425     _T ("TrayItemDelete"),
426     _T ("TrayItemGetHandle"),
427     _T ("TrayItemGetState"),
428     _T ("TrayItemGetText"),
429     _T ("TrayItemSetOnEvent"),
430     _T ("TrayItemSetState"),
431     _T ("TrayItemSetText"),
432     _T ("TraySetClick"),
433     _T ("TraySetIcon"),
434     _T ("TraySetOnEvent"),
435     _T ("TraySetPauseIcon"),
436     _T ("TraySetState"),
437     _T ("TraySetToolTip"),
438     _T ("TrayTip"),
439     _T ("True"),
440     _T ("UBound"),
441     _T ("UDPBind"),
442     _T ("UDPCloseSocket"),
443     _T ("UDPJoinMulticastGroup"),
444     _T ("UDPOpen"),
445     _T ("UDPRecv"),
446     _T ("UDPSend"),
447     _T ("UDPShutdown"),
448     _T ("UDPStartup"),
449     _T ("Until"),
450     _T ("VarGetType"),
451     _T ("Volatile"),
452     _T ("WEnd"),
453     _T ("While"),
454     _T ("WinActivate"),
455     _T ("WinActive"),
456     _T ("WinClose"),
457     _T ("WinExists"),
458     _T ("WinFlash"),
459     _T ("WinGetCaretPos"),
460     _T ("WinGetClassList"),
461     _T ("WinGetClientSize"),
462     _T ("WinGetHandle"),
463     _T ("WinGetPos"),
464     _T ("WinGetProcess"),
465     _T ("WinGetState"),
466     _T ("WinGetText"),
467     _T ("WinGetTitle"),
468     _T ("WinKill"),
469     _T ("WinList"),
470     _T ("WinMenuSelectItem"),
471     _T ("WinMinimizeAll"),
472     _T ("WinMinimizeAllUndo"),
473     _T ("WinMove"),
474     _T ("WinSetOnTop"),
475     _T ("WinSetState"),
476     _T ("WinSetTitle"),
477     _T ("WinSetTrans"),
478     _T ("WinWait"),
479     _T ("WinWaitActive"),
480     _T ("WinWaitClose"),
481     _T ("WinWaitNotActive"),
482     _T ("With"),
483   };
484
485 static bool
486 IsAutoItKeyword (const TCHAR *pszChars, int nLength)
487 {
488   return ISXKEYWORDI (s_apszAutoItKeywordList, pszChars, nLength);
489 }
490
491 static inline void
492 DefineIdentiferBlock(const TCHAR *pszChars, int nLength, CrystalLineParser::TEXTBLOCK * pBuf, int &nActualItems, int nIdentBegin, int I)
493 {
494   if (IsAutoItKeyword (pszChars + nIdentBegin, I - nIdentBegin))
495     {
496       DEFINE_BLOCK (nIdentBegin, COLORINDEX_KEYWORD);
497     }
498   else if (CrystalLineParser::IsXNumber (pszChars + nIdentBegin, I - nIdentBegin))
499     {
500       DEFINE_BLOCK (nIdentBegin, COLORINDEX_NUMBER);
501     }
502   else
503     {
504       bool bFunction = false;
505
506       for (int j = I; j < nLength; j++)
507         {
508           if (!xisspace (pszChars[j]))
509             {
510               if (pszChars[j] == '(')
511                 {
512                   bFunction = true;
513                 }
514               break;
515             }
516         }
517       if (bFunction)
518         {
519           DEFINE_BLOCK (nIdentBegin, COLORINDEX_FUNCNAME);
520         }
521     }
522 }
523
524 unsigned
525 CrystalLineParser::ParseLineAutoIt (unsigned dwCookie, const TCHAR *pszChars, int nLength, TEXTBLOCK * pBuf, int &nActualItems)
526 {
527   if (nLength == 0)
528     return dwCookie & COOKIE_EXT_COMMENT;
529
530   bool bFirstChar = (dwCookie & ~COOKIE_EXT_COMMENT) == 0;
531   bool bRedefineBlock = true;
532   bool bDecIndex = false;
533   int nIdentBegin = -1;
534   int nPrevI = -1;
535   int I=0;
536   for (I = 0;; nPrevI = I, I = static_cast<int>(::CharNext(pszChars+I) - pszChars))
537     {
538       if (I == nPrevI)
539         {
540           // CharNext did not advance, so we're at the end of the string
541           // and we already handled this character, so stop
542           break;
543         }
544
545       if (bRedefineBlock)
546         {
547           int nPos = I;
548           if (bDecIndex)
549             nPos = nPrevI;
550           if (dwCookie & (COOKIE_COMMENT | COOKIE_EXT_COMMENT))
551             {
552               DEFINE_BLOCK (nPos, COLORINDEX_COMMENT);
553             }
554           else if (dwCookie & (COOKIE_CHAR | COOKIE_STRING))
555             {
556               DEFINE_BLOCK(nPos, COLORINDEX_STRING);
557             }
558           else if (dwCookie & (COOKIE_USER1 ))
559             {
560               DEFINE_BLOCK(nPos, COLORINDEX_USER1);
561             }
562           else if (dwCookie & (COOKIE_VARIABLE))
563             {
564               DEFINE_BLOCK(nPos, COLORINDEX_USER2);
565             }
566           else if (dwCookie & COOKIE_PREPROCESSOR)
567             {
568               DEFINE_BLOCK (nPos, COLORINDEX_PREPROCESSOR);
569             }
570           else
571             {
572               if (xisalnum (pszChars[nPos]) || pszChars[nPos] == '.' && nPos > 0 && (!xisalpha (*::CharPrev(pszChars, pszChars + nPos)) && !xisalpha (*::CharNext(pszChars + nPos))))
573                 {
574                   DEFINE_BLOCK (nPos, COLORINDEX_NORMALTEXT);
575                 }
576               else
577                 {
578                   DEFINE_BLOCK (nPos, COLORINDEX_OPERATOR);
579                   bRedefineBlock = true;
580                   bDecIndex = true;
581                   goto out;
582                 }
583             }
584           bRedefineBlock = false;
585           bDecIndex = false;
586         }
587 out:
588
589       // Can be bigger than length if there is binary data
590       // See bug #1474782 Crash when comparing SQL with with binary data
591       if (I >= nLength || pszChars[I] == 0)
592         break;
593
594       if (dwCookie & COOKIE_COMMENT)
595         {
596           DEFINE_BLOCK (I, COLORINDEX_COMMENT);
597           dwCookie |= COOKIE_COMMENT;
598           break;
599         }
600
601       //  String constant '....'
602       if (dwCookie & COOKIE_CHAR)
603         {
604           if (pszChars[I] == '\'')
605             {
606               dwCookie &= ~COOKIE_CHAR;
607               bRedefineBlock = true;
608             }
609           continue;
610         }
611
612       //  String constant "...."
613       if (dwCookie & COOKIE_STRING)
614         {
615           if (pszChars[I] == '"')
616             {
617               dwCookie &= ~COOKIE_STRING;
618               bRedefineBlock = true;
619             }
620           continue;
621         }
622
623       //  Extended comment #cs .... #ce
624       if (dwCookie & COOKIE_EXT_COMMENT)
625         {
626           if (bFirstChar && pszChars[I] == '#' &&
627               ((I +  3 <= nLength && memcmp(&pszChars[I], _T("#ce"),            3 * sizeof(TCHAR)) == 0) ||
628                (I + 13 <= nLength && memcmp(&pszChars[I], _T("#comments-end"), 13 * sizeof(TCHAR)) == 0)))
629             {
630               dwCookie &= ~COOKIE_EXT_COMMENT;
631               bRedefineBlock = true;
632               bFirstChar = false;
633               I += pszChars[I + 2] == 'e' ? 2 : 12;
634             }
635           if (!xisspace (pszChars[I]))
636             bFirstChar = false;
637           continue;
638         }
639
640       if (pszChars[I] == ';')
641         {
642           DEFINE_BLOCK (I, COLORINDEX_COMMENT);
643           dwCookie |= COOKIE_COMMENT;
644           break;
645         }
646
647       //  Preprocessor directive #....
648       if (dwCookie & COOKIE_PREPROCESSOR)
649         {
650           continue;
651         }
652       // Variable begins
653       
654       // Variable begins
655       if (pszChars[I] == '@')
656         {
657           DEFINE_BLOCK(I, COLORINDEX_USER1);
658           dwCookie |= COOKIE_USER1;
659           continue;
660         }
661
662       // Variable ends
663       if (dwCookie & COOKIE_USER1)
664         {
665           if (!xisalnum(pszChars[I]))
666             {
667               dwCookie &= ~COOKIE_USER1;
668               bRedefineBlock = true;
669               bDecIndex = true;
670             }
671           continue;
672         }
673       
674       if (pszChars[I] == '$')
675         {
676           DEFINE_BLOCK(I, COLORINDEX_USER2);
677           dwCookie |= COOKIE_VARIABLE;
678           continue;
679         }
680
681       // Variable ends
682       if (dwCookie & COOKIE_VARIABLE)
683         {
684           if (!xisalnum(pszChars[I]))
685             {
686               dwCookie &= ~COOKIE_VARIABLE;
687               bRedefineBlock = true;
688               bDecIndex = true;
689             }
690           continue;
691         }
692
693       //  Normal text
694       if (pszChars[I] == '"')
695         {
696           DEFINE_BLOCK (I, COLORINDEX_STRING);
697           dwCookie |= COOKIE_STRING;
698           continue;
699         }
700
701       //  Normal text
702       if (pszChars[I] == '\'')
703         {
704           DEFINE_BLOCK (I, COLORINDEX_STRING);
705           dwCookie |= COOKIE_CHAR;
706           continue;
707         }
708
709       if (bFirstChar)
710         {
711           if (pszChars[I] == '#')
712             {
713               if ((I +  3 <= nLength && memcmp(&pszChars[I], _T("#cs"),              3 * sizeof(TCHAR)) == 0) ||
714                   (I + 15 <= nLength && memcmp(&pszChars[I], _T("#comments-start"), 15 * sizeof(TCHAR)) == 0))
715                 {
716                   DEFINE_BLOCK (I, COLORINDEX_COMMENT);
717                   dwCookie |= COOKIE_EXT_COMMENT;
718                 }
719               else
720                 {
721                   DEFINE_BLOCK(I, COLORINDEX_PREPROCESSOR);
722                   dwCookie |= COOKIE_PREPROCESSOR;
723                 }
724               bFirstChar = false;
725               continue;
726             }
727           if (!xisspace (pszChars[I]))
728             bFirstChar = false;
729         }
730
731       if (pBuf == nullptr)
732         continue;               //  We don't need to extract keywords,
733       //  for faster parsing skip the rest of loop
734
735       if (xisalnum (pszChars[I]) || pszChars[I] == '.' && I > 0 && (!xisalpha (pszChars[nPrevI]) && !xisalpha (pszChars[I + 1])))
736         {
737           if (nIdentBegin == -1)
738             nIdentBegin = I;
739         }
740       else
741         {
742           if (nIdentBegin >= 0)
743             {
744               DefineIdentiferBlock(pszChars, nLength, pBuf, nActualItems, nIdentBegin, I);
745               bRedefineBlock = true;
746               bDecIndex = true;
747               nIdentBegin = -1;
748             }
749         }
750     }
751
752   if (nIdentBegin >= 0)
753     DefineIdentiferBlock(pszChars, nLength, pBuf, nActualItems, nIdentBegin, I);
754
755   dwCookie &= COOKIE_EXT_COMMENT;
756   return dwCookie;
757 }