1 // Scintilla source code edit control
2 /** @file LexSorcus.cxx
3 ** Lexer for SORCUS installation files
4 ** Written by Eugen Bitter and Christoph Baumann at SORCUS Computer, Heidelberg Germany
5 ** Based on the ASM Lexer by The Black Horus
6 **/
7 
8 // The License.txt file describes the conditions under which this software may be distributed.
9 
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <stdarg.h>
14 #include <assert.h>
15 #include <ctype.h>
16 
17 #include "ILexer.h"
18 #include "Scintilla.h"
19 #include "SciLexer.h"
20 
21 #include "WordList.h"
22 #include "LexAccessor.h"
23 #include "Accessor.h"
24 #include "StyleContext.h"
25 #include "CharacterSet.h"
26 #include "LexerModule.h"
27 
28 using namespace Scintilla;
29 
30 
31 //each character a..z and A..Z + '_' can be part of a keyword
32 //additionally numbers that follow 'M' can be contained in a keyword
IsSWordStart(const int ch,const int prev_ch)33 static inline bool IsSWordStart(const int ch, const int prev_ch)
34 {
35     if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
36         return true;
37 
38     return false;
39 }
40 
41 
42 //only digits that are not preceded by 'M' count as a number
IsSorcusNumber(const int ch,const int prev_ch)43 static inline bool IsSorcusNumber(const int ch, const int prev_ch)
44 {
45     if ((isdigit(ch)) && (prev_ch != 'M'))
46         return true;
47 
48     return false;
49 }
50 
51 
52 //only = is a valid operator
IsSorcusOperator(const int ch)53 static inline bool IsSorcusOperator(const int ch)
54 {
55     if (ch == '=')
56         return true;
57 
58     return false;
59 }
60 
61 
ColouriseSorcusDoc(Sci_PositionU startPos,Sci_Position length,int initStyle,WordList * keywordlists[],Accessor & styler)62 static void ColouriseSorcusDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[],
63                                Accessor &styler)
64 {
65 
66     WordList &Command = *keywordlists[0];
67     WordList &Parameter = *keywordlists[1];
68     WordList &Constant = *keywordlists[2];
69 
70     // Do not leak onto next line
71     if (initStyle == SCE_SORCUS_STRINGEOL)
72         initStyle = SCE_SORCUS_DEFAULT;
73 
74     StyleContext sc(startPos, length, initStyle, styler);
75 
76     for (; sc.More(); sc.Forward())
77     {
78 
79         // Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
80         if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
81         {
82             sc.SetState(SCE_SORCUS_STRING);
83         }
84 
85         // Determine if the current state should terminate.
86         if (sc.state == SCE_SORCUS_OPERATOR)
87         {
88             if (!IsSorcusOperator(sc.ch))
89             {
90                 sc.SetState(SCE_SORCUS_DEFAULT);
91             }
92         }
93         else if(sc.state == SCE_SORCUS_NUMBER)
94         {
95             if(!IsSorcusNumber(sc.ch, sc.chPrev))
96             {
97                 sc.SetState(SCE_SORCUS_DEFAULT);
98             }
99         }
100         else if (sc.state == SCE_SORCUS_IDENTIFIER)
101         {
102             if (!IsSWordStart(sc.ch, sc.chPrev))
103             {
104                 char s[100];
105 
106                 sc.GetCurrent(s, sizeof(s));
107 
108                 if (Command.InList(s))
109                 {
110                     sc.ChangeState(SCE_SORCUS_COMMAND);
111                 }
112                 else if (Parameter.InList(s))
113                 {
114                     sc.ChangeState(SCE_SORCUS_PARAMETER);
115                 }
116                 else if (Constant.InList(s))
117                 {
118                     sc.ChangeState(SCE_SORCUS_CONSTANT);
119                 }
120 
121                 sc.SetState(SCE_SORCUS_DEFAULT);
122             }
123         }
124         else if (sc.state == SCE_SORCUS_COMMENTLINE )
125         {
126             if (sc.atLineEnd)
127             {
128                 sc.SetState(SCE_SORCUS_DEFAULT);
129             }
130         }
131         else if (sc.state == SCE_SORCUS_STRING)
132         {
133             if (sc.ch == '\"')
134             {
135                 sc.ForwardSetState(SCE_SORCUS_DEFAULT);
136             }
137             else if (sc.atLineEnd)
138             {
139                 sc.ChangeState(SCE_SORCUS_STRINGEOL);
140                 sc.ForwardSetState(SCE_SORCUS_DEFAULT);
141             }
142         }
143 
144         // Determine if a new state should be entered.
145         if (sc.state == SCE_SORCUS_DEFAULT)
146         {
147             if ((sc.ch == ';') || (sc.ch == '\''))
148             {
149                 sc.SetState(SCE_SORCUS_COMMENTLINE);
150             }
151             else if (IsSWordStart(sc.ch, sc.chPrev))
152             {
153                 sc.SetState(SCE_SORCUS_IDENTIFIER);
154             }
155             else if (sc.ch == '\"')
156             {
157                 sc.SetState(SCE_SORCUS_STRING);
158             }
159             else if (IsSorcusOperator(sc.ch))
160             {
161                 sc.SetState(SCE_SORCUS_OPERATOR);
162             }
163             else if (IsSorcusNumber(sc.ch, sc.chPrev))
164             {
165                 sc.SetState(SCE_SORCUS_NUMBER);
166             }
167         }
168 
169     }
170     sc.Complete();
171 }
172 
173 
174 static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
175 
176 LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
177 
178 
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205 
206 
207