Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 231 lines (201 sloc) 7.078 kb
f858c4b @djs Import Scintilla 2.11
authored
1 // Scintilla source code edit control
2 /** @file LexFlagShip.cxx
3 ** Lexer for FlagShip
4 ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
5 **/
6 // Copyright 2005 by Randy Butler
7 // Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
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 <ctype.h>
13 #include <stdio.h>
14 #include <stdarg.h>
15
16 #include "Platform.h"
17
18 #include "PropSet.h"
19 #include "Accessor.h"
20 #include "StyleContext.h"
21 #include "KeyWords.h"
22 #include "Scintilla.h"
23 #include "SciLexer.h"
24
25 #ifdef SCI_NAMESPACE
26 using namespace Scintilla;
27 #endif
28
29 static bool IsFlagShipComment(Accessor &styler, int pos, int len) {
30 return len>0 && styler[pos]=='\'';
31 }
32
33 static inline bool IsTypeCharacter(int ch) {
34 return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
35 }
36
37 // Extended to accept accented characters
38 static inline bool IsAWordChar(int ch) {
39 return ch >= 0x80 ||
40 (isalnum(ch) || ch == '.' || ch == '_');
41 }
42
43 static inline bool IsAWordStart(int ch) {
44 return ch >= 0x80 ||
45 (isalnum(ch) || ch == '_');
46 }
47
48 static inline bool IsADateCharacter(const int ch) {
49 return (ch < 0x80) &&
50 (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
51 }
52
53
54 static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
55 WordList *keywordlists[], Accessor &styler) {
56
57 //bool FSScriptSyntax = true;
58 WordList &keywords = *keywordlists[0];
59 WordList &keywords2 = *keywordlists[1];
60 WordList &keywords3 = *keywordlists[2];
61 WordList &keywords4 = *keywordlists[3];
62
63 styler.StartAt(startPos);
64
65 int visibleChars = 0;
66
67 StyleContext sc(startPos, length, initStyle, styler);
68
69 for (; sc.More(); sc.Forward()) {
70
71 if (sc.state == SCE_FS_OPERATOR) {
72 sc.SetState(SCE_FS_DEFAULT);
73 } else if (sc.state == SCE_FS_IDENTIFIER) {
74 if (!IsAWordChar(sc.ch)) {
75 char s[100];
76 sc.GetCurrentLowered(s, sizeof(s));
77 if (keywords.InList(s)) {
78 sc.ChangeState(SCE_FS_KEYWORD);
79 } else if (keywords2.InList(s)) {
80 sc.ChangeState(SCE_FS_KEYWORD2);
81 } else if (keywords3.InList(s)) {
82 sc.ChangeState(SCE_FS_KEYWORD3);
83 } else if (keywords4.InList(s)) {
84 sc.ChangeState(SCE_FS_KEYWORD4);
85 }// Else, it is really an identifier...
86 sc.SetState(SCE_FS_DEFAULT);
87 }
88 } else if (sc.state == SCE_FS_NUMBER) {
89 if (!IsAWordChar(sc.ch)) {
90 sc.SetState(SCE_FS_DEFAULT);
91 }
92 } else if (sc.state == SCE_FS_STRING) {
93 // VB doubles quotes to preserve them, so just end this string
94 // state now as a following quote will start again
95 if (sc.ch == '\"') {
96 if (tolower(sc.chNext) == 'c') {
97 sc.Forward();
98 }
99 sc.ForwardSetState(SCE_FS_DEFAULT);
100 } else if (sc.atLineEnd) {
101 sc.ChangeState(SCE_FS_STRINGEOL);
102 sc.ForwardSetState(SCE_FS_DEFAULT);
103 }
104 } else if (sc.state == SCE_FS_COMMENT) {
105 if (sc.Match('*', '/')) { // new code
106 sc.Forward();
107 sc.ForwardSetState(SCE_FS_DEFAULT);
108 //if (sc.atLineEnd) { // old code
109 // sc.SetState(SCE_FS_DEFAULT);
110 }
111 } else if (sc.state == SCE_FS_COMMENTLINE) { //new code
112 if (sc.ch == '\r' || sc.ch == '\n') {
113 sc.SetState(SCE_FS_DEFAULT);
114 visibleChars = 0;
115 }
116 } else if (sc.state == SCE_FS_PREPROCESSOR) {
117 if (sc.atLineEnd) {
118 sc.SetState(SCE_FS_DEFAULT);
119 }
120 } else if (sc.state == SCE_FS_DATE) {
121 if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
122 sc.ForwardSetState(SCE_FS_DEFAULT);
123 }
124 }
125
126 // Determine if a new state should be entered.
127 if (sc.state == SCE_FS_DEFAULT) {
128 if (sc.Match('/', '*')) { // New code
129 sc.SetState(SCE_FS_COMMENT);
130 sc.Forward(); // Eat the * so it isn't used for the end of the comment
131 //if (sc.ch == '\'') { // Old code
132 // sc.SetState(SCE_FS_COMMENT); // old code
133 } else if (sc.Match('/', '/')) { // New code
134 sc.SetState(SCE_FS_COMMENTLINE);
135 } else if (sc.ch == '\"') {
136 sc.SetState(SCE_FS_STRING);
137 } else if (sc.ch == '#' && visibleChars == 0) {
138 // Preprocessor commands are alone on their line
139 sc.SetState(SCE_FS_PREPROCESSOR);
140 } else if (sc.ch == '#') {
141 int n = 1;
142 int chSeek = ' ';
143 while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
144 chSeek = sc.GetRelative(n);
145 n++;
146 }
147 if (IsADigit(chSeek)) {
148 sc.SetState(SCE_FS_DATE);
149 } else {
150 sc.SetState(SCE_FS_OPERATOR);
151 }
152 } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
153 sc.SetState(SCE_FS_NUMBER);
154 } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
155 sc.SetState(SCE_FS_NUMBER);
156 } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
157 sc.SetState(SCE_FS_NUMBER);
158 } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
159 sc.SetState(SCE_FS_IDENTIFIER);
160 } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
161 sc.SetState(SCE_FS_OPERATOR);
162 }
163 }
164
165 if (sc.atLineEnd) {
166 visibleChars = 0;
167 }
168 if (!IsASpace(sc.ch)) {
169 visibleChars++;
170 }
171 }
172 sc.Complete();
173 }
174
175 static void FoldFlagShipDoc(unsigned int startPos, int length, int,
176 WordList *[], Accessor &styler) {
177
178 int endPos = startPos + length;
179
180 // Backtrack to previous line in case need to fix its fold status
181 int lineCurrent = styler.GetLine(startPos);
182 if (startPos > 0) {
183 if (lineCurrent > 0) {
184 lineCurrent--;
185 startPos = styler.LineStart(lineCurrent);
186 }
187 }
188 int spaceFlags = 0;
189 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsFlagShipComment);
190 char chNext = styler[startPos];
191 for (int i = startPos; i < endPos; i++) {
192 char ch = chNext;
193 chNext = styler.SafeGetCharAt(i + 1);
194
195 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
196 int lev = indentCurrent;
197 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsFlagShipComment);
198 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
199 // Only non whitespace lines can be headers
200 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
201 lev |= SC_FOLDLEVELHEADERFLAG;
202 } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
203 // Line after is blank so check the next - maybe should continue further?
204 int spaceFlags2 = 0;
205 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsFlagShipComment);
206 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
207 lev |= SC_FOLDLEVELHEADERFLAG;
208 }
209 }
210 }
211 indentCurrent = indentNext;
212 styler.SetLevel(lineCurrent, lev);
213 lineCurrent++;
214 }
215 }
216 }
217
218
219 static const char * const FSWordListDesc[] = {
220 "Keywords",
221 "functions",
222 "user2",
223 "user3",
224 0
225 };
226
227 LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
228
229
230
Something went wrong with that request. Please try again.