]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/src/LexMatlab.cxx
compilation fix for ANSI build (added #if wxUSE_UNICODE)
[wxWidgets.git] / src / stc / scintilla / src / LexMatlab.cxx
1 // Scintilla source code edit control
2 /** @file LexMatlab.cxx
3 ** Lexer for Matlab.
4 ** Written by José Fonseca
5 **
6 ** Changes by Christoph Dalitz 2003/12/04:
7 ** - added support for Octave
8 ** - Strings can now be included both in single or double quotes
9 **/
10 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
11 // The License.txt file describes the conditions under which this software may be distributed.
12
13 #include <stdlib.h>
14 #include <string.h>
15 #include <ctype.h>
16 #include <stdio.h>
17 #include <stdarg.h>
18
19 #include "Platform.h"
20
21 #include "PropSet.h"
22 #include "Accessor.h"
23 #include "StyleContext.h"
24 #include "KeyWords.h"
25 #include "Scintilla.h"
26 #include "SciLexer.h"
27
28
29 static bool IsMatlabCommentChar(int c) {
30 return (c == '%') ;
31 }
32
33 static bool IsOctaveCommentChar(int c) {
34 return (c == '%' || c == '#') ;
35 }
36
37 static bool IsMatlabComment(Accessor &styler, int pos, int len) {
38 return len > 0 && IsMatlabCommentChar(styler[pos]) ;
39 }
40
41 static bool IsOctaveComment(Accessor &styler, int pos, int len) {
42 return len > 0 && IsOctaveCommentChar(styler[pos]) ;
43 }
44
45 static inline bool IsAWordChar(const int ch) {
46 return (ch < 0x80) && (isalnum(ch) || ch == '_');
47 }
48
49 static inline bool IsAWordStart(const int ch) {
50 return (ch < 0x80) && (isalnum(ch) || ch == '_');
51 }
52
53 static void ColouriseMatlabOctaveDoc(
54 unsigned int startPos, int length, int initStyle,
55 WordList *keywordlists[], Accessor &styler,
56 bool (*IsCommentChar)(int)) {
57
58 WordList &keywords = *keywordlists[0];
59
60 styler.StartAt(startPos);
61
62 bool transpose = false;
63
64 StyleContext sc(startPos, length, initStyle, styler);
65
66 for (; sc.More(); sc.Forward()) {
67
68 if (sc.state == SCE_MATLAB_OPERATOR) {
69 if (sc.chPrev == '.') {
70 if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
71 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
72 transpose = false;
73 } else if (sc.ch == '\'') {
74 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
75 transpose = true;
76 } else {
77 sc.SetState(SCE_MATLAB_DEFAULT);
78 }
79 } else {
80 sc.SetState(SCE_MATLAB_DEFAULT);
81 }
82 } else if (sc.state == SCE_MATLAB_KEYWORD) {
83 if (!isalnum(sc.ch) && sc.ch != '_') {
84 char s[100];
85 sc.GetCurrentLowered(s, sizeof(s));
86 if (keywords.InList(s)) {
87 sc.SetState(SCE_MATLAB_DEFAULT);
88 transpose = false;
89 } else {
90 sc.ChangeState(SCE_MATLAB_IDENTIFIER);
91 sc.SetState(SCE_MATLAB_DEFAULT);
92 transpose = true;
93 }
94 }
95 } else if (sc.state == SCE_MATLAB_NUMBER) {
96 if (!isdigit(sc.ch) && sc.ch != '.'
97 && !(sc.ch == 'e' || sc.ch == 'E')
98 && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
99 sc.SetState(SCE_MATLAB_DEFAULT);
100 transpose = true;
101 }
102 } else if (sc.state == SCE_MATLAB_STRING) {
103 if (sc.ch == '\'' && sc.chPrev != '\\') {
104 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
105 }
106 } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
107 if (sc.ch == '"' && sc.chPrev != '\\') {
108 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
109 }
110 } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
111 if (sc.atLineEnd) {
112 sc.SetState(SCE_MATLAB_DEFAULT);
113 transpose = false;
114 }
115 }
116
117 if (sc.state == SCE_MATLAB_DEFAULT) {
118 if (IsCommentChar(sc.ch)) {
119 sc.SetState(SCE_MATLAB_COMMENT);
120 } else if (sc.ch == '!') {
121 sc.SetState(SCE_MATLAB_COMMAND);
122 } else if (sc.ch == '\'') {
123 if (transpose) {
124 sc.SetState(SCE_MATLAB_OPERATOR);
125 } else {
126 sc.SetState(SCE_MATLAB_STRING);
127 }
128 } else if (sc.ch == '"') {
129 sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
130 } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
131 sc.SetState(SCE_MATLAB_NUMBER);
132 } else if (isalpha(sc.ch)) {
133 sc.SetState(SCE_MATLAB_KEYWORD);
134 } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
135 if (sc.ch == ')' || sc.ch == ']') {
136 transpose = true;
137 } else {
138 transpose = false;
139 }
140 sc.SetState(SCE_MATLAB_OPERATOR);
141 } else {
142 transpose = false;
143 }
144 }
145 }
146 sc.Complete();
147 }
148
149 static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
150 WordList *keywordlists[], Accessor &styler) {
151 ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
152 }
153
154 static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
155 WordList *keywordlists[], Accessor &styler) {
156 ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
157 }
158
159 static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int,
160 WordList *[], Accessor &styler,
161 bool (*IsComment)(Accessor&,int,int)) {
162
163 int endPos = startPos + length;
164
165 // Backtrack to previous line in case need to fix its fold status
166 int lineCurrent = styler.GetLine(startPos);
167 if (startPos > 0) {
168 if (lineCurrent > 0) {
169 lineCurrent--;
170 startPos = styler.LineStart(lineCurrent);
171 }
172 }
173 int spaceFlags = 0;
174 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
175 char chNext = styler[startPos];
176 for (int i = startPos; i < endPos; i++) {
177 char ch = chNext;
178 chNext = styler.SafeGetCharAt(i + 1);
179
180 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
181 int lev = indentCurrent;
182 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
183 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
184 // Only non whitespace lines can be headers
185 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
186 lev |= SC_FOLDLEVELHEADERFLAG;
187 } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
188 // Line after is blank so check the next - maybe should continue further?
189 int spaceFlags2 = 0;
190 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
191 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
192 lev |= SC_FOLDLEVELHEADERFLAG;
193 }
194 }
195 }
196 indentCurrent = indentNext;
197 styler.SetLevel(lineCurrent, lev);
198 lineCurrent++;
199 }
200 }
201 }
202
203 static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
204 WordList *keywordlists[], Accessor &styler) {
205 FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
206 }
207
208 static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
209 WordList *keywordlists[], Accessor &styler) {
210 FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
211 }
212
213 static const char * const matlabWordListDesc[] = {
214 "Keywords",
215 0
216 };
217
218 static const char * const octaveWordListDesc[] = {
219 "Keywords",
220 0
221 };
222
223 LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc);
224
225 LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc);