]>
git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexFlagship.cxx
1 // Scintilla source code edit control
2 /** @file LexFlagShip.cxx
4 ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
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.
20 #include "StyleContext.h"
22 #include "Scintilla.h"
26 using namespace Scintilla
;
29 static bool IsFlagShipComment(Accessor
&styler
, int pos
, int len
) {
30 return len
>0 && styler
[pos
]=='\'';
33 static inline bool IsTypeCharacter(int ch
) {
34 return ch
== '%' || ch
== '&' || ch
== '@' || ch
== '!' || ch
== '#' || ch
== '$';
37 // Extended to accept accented characters
38 static inline bool IsAWordChar(int ch
) {
40 (isalnum(ch
) || ch
== '.' || ch
== '_');
43 static inline bool IsAWordStart(int ch
) {
45 (isalnum(ch
) || ch
== '_');
48 static inline bool IsADateCharacter(const int ch
) {
50 (isalnum(ch
) || ch
== '|' || ch
== '-' || ch
== '/' || ch
== ':' || ch
== ' ' || ch
== '\t');
54 static void ColouriseFlagShipDoc(unsigned int startPos
, int length
, int initStyle
,
55 WordList
*keywordlists
[], Accessor
&styler
) {
57 //bool FSScriptSyntax = true;
58 WordList
&keywords
= *keywordlists
[0];
59 WordList
&keywords2
= *keywordlists
[1];
60 WordList
&keywords3
= *keywordlists
[2];
61 WordList
&keywords4
= *keywordlists
[3];
63 styler
.StartAt(startPos
);
67 StyleContext
sc(startPos
, length
, initStyle
, styler
);
69 for (; sc
.More(); sc
.Forward()) {
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
)) {
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
);
88 } else if (sc
.state
== SCE_FS_NUMBER
) {
89 if (!IsAWordChar(sc
.ch
)) {
90 sc
.SetState(SCE_FS_DEFAULT
);
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
96 if (tolower(sc
.chNext
) == 'c') {
99 sc
.ForwardSetState(SCE_FS_DEFAULT
);
100 } else if (sc
.atLineEnd
) {
101 sc
.ChangeState(SCE_FS_STRINGEOL
);
102 sc
.ForwardSetState(SCE_FS_DEFAULT
);
104 } else if (sc
.state
== SCE_FS_COMMENT
) {
105 if (sc
.Match('*', '/')) { // new code
107 sc
.ForwardSetState(SCE_FS_DEFAULT
);
108 //if (sc.atLineEnd) { // old code
109 // sc.SetState(SCE_FS_DEFAULT);
111 } else if (sc
.state
== SCE_FS_COMMENTLINE
) { //new code
112 if (sc
.ch
== '\r' || sc
.ch
== '\n') {
113 sc
.SetState(SCE_FS_DEFAULT
);
116 } else if (sc
.state
== SCE_FS_PREPROCESSOR
) {
118 sc
.SetState(SCE_FS_DEFAULT
);
120 } else if (sc
.state
== SCE_FS_DATE
) {
121 if (sc
.ch
== '#' || !IsADateCharacter(sc
.chNext
)) {
122 sc
.ForwardSetState(SCE_FS_DEFAULT
);
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
== '#') {
143 while ((n
< 100) && (chSeek
== ' ' || chSeek
== '\t')) {
144 chSeek
= sc
.GetRelative(n
);
147 if (IsADigit(chSeek
)) {
148 sc
.SetState(SCE_FS_DATE
);
150 sc
.SetState(SCE_FS_OPERATOR
);
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
);
168 if (!IsASpace(sc
.ch
)) {
175 static void FoldFlagShipDoc(unsigned int startPos
, int length
, int,
176 WordList
*[], Accessor
&styler
) {
178 int endPos
= startPos
+ length
;
180 // Backtrack to previous line in case need to fix its fold status
181 int lineCurrent
= styler
.GetLine(startPos
);
183 if (lineCurrent
> 0) {
185 startPos
= styler
.LineStart(lineCurrent
);
189 int indentCurrent
= styler
.IndentAmount(lineCurrent
, &spaceFlags
, IsFlagShipComment
);
190 char chNext
= styler
[startPos
];
191 for (int i
= startPos
; i
< endPos
; i
++) {
193 chNext
= styler
.SafeGetCharAt(i
+ 1);
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?
205 int indentNext2
= styler
.IndentAmount(lineCurrent
+ 2, &spaceFlags2
, IsFlagShipComment
);
206 if ((indentCurrent
& SC_FOLDLEVELNUMBERMASK
) < (indentNext2
& SC_FOLDLEVELNUMBERMASK
)) {
207 lev
|= SC_FOLDLEVELHEADERFLAG
;
211 indentCurrent
= indentNext
;
212 styler
.SetLevel(lineCurrent
, lev
);
219 static const char * const FSWordListDesc
[] = {
227 LexerModule
lmFlagShip(SCLEX_FLAGSHIP
, ColouriseFlagShipDoc
, "flagship", FoldFlagShipDoc
, FSWordListDesc
);