NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
LexMatlab.cxx
Go to the documentation of this file.
1// Scintilla source code edit control
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 <stdio.h>
16#include <stdarg.h>
17#include <assert.h>
18#include <ctype.h>
19
20#include "ILexer.h"
21#include "Scintilla.h"
22#include "SciLexer.h"
23
24#include "WordList.h"
25#include "LexAccessor.h"
26#include "Accessor.h"
27#include "StyleContext.h"
28#include "CharacterSet.h"
29#include "LexerModule.h"
30
31#ifdef SCI_NAMESPACE
32using namespace Scintilla;
33#endif
34
35static bool IsMatlabCommentChar(int c) {
36 return (c == '%') ;
37}
38
39static bool IsOctaveCommentChar(int c) {
40 return (c == '%' || c == '#') ;
41}
42
43static bool IsMatlabComment(Accessor &styler, int pos, int len) {
44 return len > 0 && IsMatlabCommentChar(styler[pos]) ;
45}
46
47static bool IsOctaveComment(Accessor &styler, int pos, int len) {
48 return len > 0 && IsOctaveCommentChar(styler[pos]) ;
49}
50
51static inline bool IsAWordChar(const int ch) {
52 return (ch < 0x80) && (isalnum(ch) || ch == '_');
53}
54
55static inline bool IsAWordStart(const int ch) {
56 return (ch < 0x80) && (isalnum(ch) || ch == '_');
57}
58
59// This function determines the opening and closing parentheses until
60// the passed position. It is assumed that the block until the passed
61// position is already styled
62static int GetParenthesesCount(unsigned int startPos, Accessor& styler)
63{
64 int nParentheses = 0;
65 for (size_t i = 0; i < startPos; i++)
66 {
67 char currentChar = styler.SafeGetCharAt(i);
68 if (styler.StyleAt(i) == SCE_MATLAB_OPERATOR || styler.StyleAt(i) == SCE_MATLAB_DEFAULT)
69 {
70 if (currentChar == '(' || currentChar == '[' || currentChar == '{')
71 nParentheses++;
72 else if (currentChar == ')' || currentChar == ']' || currentChar == '}')
73 nParentheses--;
74 }
75 }
76 return nParentheses;
77}
78
80 unsigned int startPos, int length, int initStyle,
81 WordList *keywordlists[], Accessor &styler,
82 bool (*IsCommentChar)(int)) {
83
84 WordList &keywords = *keywordlists[0];
85 WordList &keywords2 = *keywordlists[1];
86
87 styler.StartAt(startPos);
88
89 bool transpose = false;
90
91 StyleContext sc(startPos, length, initStyle, styler);
92
93 // Get the parentheses before the current block
94 int nParens = GetParenthesesCount(startPos, styler);
95
96 for (; sc.More(); sc.Forward()) {
97
98 if (sc.state == SCE_MATLAB_OPERATOR) {
99 if (sc.chPrev == '.') {
100 if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\' || sc.ch == '^') {
101 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
102 transpose = false;
103 } else if (sc.ch == '\'') {
104 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
105 transpose = true;
106 } else {
107 sc.SetState(SCE_MATLAB_DEFAULT);
108 }
109 } else {
110 sc.SetState(SCE_MATLAB_DEFAULT);
111 }
112 } else if (sc.state == SCE_MATLAB_KEYWORD) {
113 if (!isalnum(sc.ch) && sc.ch != '_') {
114 char s[100];
115 sc.GetCurrentLowered(s, sizeof(s));
116 if (!strcmp(s, "end") && nParens)
117 {
118 sc.ChangeState(SCE_MATLAB_IDENTIFIER);
119 sc.SetState(SCE_MATLAB_DEFAULT);
120 transpose = true;
121 }
122 else if (keywords.InList(s)) {
123 sc.SetState(SCE_MATLAB_DEFAULT);
124 transpose = false;
125 } else if (keywords2.InList(s)) {
126 sc.ChangeState(SCE_MATLAB_FUNCTIONS);
127 sc.SetState(SCE_MATLAB_DEFAULT);
128 transpose = false;
129 } else {
130 sc.ChangeState(SCE_MATLAB_IDENTIFIER);
131 sc.SetState(SCE_MATLAB_DEFAULT);
132 transpose = true;
133 }
134 }
135 } else if (sc.state == SCE_MATLAB_NUMBER) {
136 if (!isdigit(sc.ch) && sc.ch != '.'
137 && !(sc.ch == 'e' || sc.ch == 'E')
138 && !((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E'))) {
139 sc.SetState(SCE_MATLAB_DEFAULT);
140 transpose = true;
141 }
142 } else if (sc.state == SCE_MATLAB_STRING) {
143 if (sc.ch == '\'') {
144 if (sc.chNext == '\'') {
145 sc.Forward();
146 } else {
147 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
148 }
149 }
150 } else if (sc.state == SCE_MATLAB_DOUBLEQUOTESTRING) {
151 if (sc.ch == '\\') {
152 if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
153 sc.Forward();
154 }
155 } else if (sc.ch == '\"') {
156 sc.ForwardSetState(SCE_MATLAB_DEFAULT);
157 }
158 } else if (sc.state == SCE_MATLAB_COMMENT || sc.state == SCE_MATLAB_COMMAND) {
159 if (sc.atLineEnd) {
160 sc.SetState(SCE_MATLAB_DEFAULT);
161 transpose = false;
162 }
163 }
164
165 if (sc.state == SCE_MATLAB_DEFAULT) {
166 if (IsCommentChar(sc.ch)) {
167 sc.SetState(SCE_MATLAB_COMMENT);
168 } else if (sc.ch == '!' && sc.chNext != '=' ) {
169 sc.SetState(SCE_MATLAB_COMMAND);
170 } else if (sc.ch == '\'') {
171 if (transpose) {
172 sc.SetState(SCE_MATLAB_OPERATOR);
173 } else {
174 sc.SetState(SCE_MATLAB_STRING);
175 }
176 } else if (sc.ch == '"') {
177 sc.SetState(SCE_MATLAB_DOUBLEQUOTESTRING);
178 } else if (isdigit(sc.ch) || (sc.ch == '.' && isdigit(sc.chNext))) {
179 sc.SetState(SCE_MATLAB_NUMBER);
180 } else if (isalpha(sc.ch)) {
181 sc.SetState(SCE_MATLAB_KEYWORD);
182 } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '\\') {
183 if (sc.ch == ')' || sc.ch == ']' || sc.ch == '}') {
184 transpose = true;
185 } else {
186 transpose = false;
187 }
188 if (sc.ch == '(' || sc.ch == '[' || sc.ch == '{')
189 nParens++;
190 if (sc.ch == ')' || sc.ch == ']' || sc.ch == '}')
191 nParens--;
192 sc.SetState(SCE_MATLAB_OPERATOR);
193 } else {
194 transpose = false;
195 }
196 }
197 }
198 sc.Complete();
199}
200
201static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle,
202 WordList *keywordlists[], Accessor &styler) {
203 ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabCommentChar);
204}
205
206static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle,
207 WordList *keywordlists[], Accessor &styler) {
208 ColouriseMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveCommentChar);
209}
210
211static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int initStyle,
212 WordList *[], Accessor &styler,
213 bool (*IsComment)(Accessor&, int, int)) {
214
215 unsigned int endPos = startPos + length;
216 int visibleChars = 0;
217 int lineCurrent = styler.GetLine(startPos);
218 int levelCurrent = SC_FOLDLEVELBASE;
219 if (lineCurrent > 0)
220 levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
221 int levelMinCurrent = levelCurrent;
222 int levelNext = levelCurrent;
223 char chNext = styler[startPos];
224 int styleNext = styler.StyleAt(startPos);
225 int style = initStyle;
226 for (unsigned int i = startPos; i < endPos; i++)
227 {
228 char ch = chNext;
229 chNext = styler.SafeGetCharAt(i + 1);
230 int stylePrev = style;
231 style = styleNext;
232 styleNext = styler.StyleAt(i + 1);
233 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
234
235 if (style == SCE_MATLAB_OPERATOR &&
236 (styler.SafeGetCharAt(i) == '('
237 || styler.SafeGetCharAt(i) == '{'
238 || styler.SafeGetCharAt(i) == '[')
239 )
240 {
241 int nPar = 0;
242 for (int j = i; j < endPos; j++)
243 {
244 atEOL = (styler.SafeGetCharAt(j) == '\r' && styler.SafeGetCharAt(j+1) != '\n')
245 || (styler.SafeGetCharAt(j) == '\n');
246 if (styler.StyleAt(j) == SCE_MATLAB_OPERATOR &&
247 (styler.SafeGetCharAt(j) == '('
248 || styler.SafeGetCharAt(j) == '{'
249 || styler.SafeGetCharAt(j) == '['))
250 nPar++;
251 if (styler.StyleAt(j) == SCE_MATLAB_OPERATOR &&
252 (styler.SafeGetCharAt(j) == ')'
253 || styler.SafeGetCharAt(j) == '}'
254 || styler.SafeGetCharAt(j) == ']'))
255 nPar--;
256 if (atEOL)
257 {
258 int levelUse = levelCurrent;
259 levelUse = levelMinCurrent;
260 int lev = levelUse | levelNext << 16;
261 /*if (visibleChars == 0)
262 lev |= SC_FOLDLEVELWHITEFLAG;*/
263 if (levelUse < levelNext)
264 lev |= SC_FOLDLEVELHEADERFLAG;
265 if (lev != styler.LevelAt(lineCurrent))
266 {
267 styler.SetLevel(lineCurrent, lev);
268 }
269 lineCurrent++;
270 levelCurrent = levelNext;
271 levelMinCurrent = levelCurrent;
272 visibleChars = 0;
273 }
274 if (!nPar)
275 {
276 i = j-1;
277 break;
278 }
279 }
280 continue;
281 }
282 if (style == SCE_MATLAB_KEYWORD)
283 {
284 if (styler.Match(i, "end"))
285 {
286 levelNext--;
287 }
288 else if (styler.SafeGetCharAt(i-1) != 'e'
289 && (styler.Match(i, "if")
290 || styler.Match(i, "for")
291 || styler.Match(i, "while")
292 || styler.Match(i, "do")
293 || styler.Match(i, "switch")
294 || styler.Match(i, "try")
295 || styler.Match(i, "classdef")
296 || styler.Match(i, "methods")
297 || styler.Match(i, "properties")
298 || styler.Match(i, "function"))
299 )
300 {
301 levelNext++;
302 }
303 }
304 if (atEOL || (i == endPos-1))
305 {
306 int levelUse = levelCurrent;
307 levelUse = levelMinCurrent;
308 int lev = levelUse | levelNext << 16;
309 /*if (visibleChars == 0)
310 lev |= SC_FOLDLEVELWHITEFLAG;*/
311 if (levelUse < levelNext)
312 lev |= SC_FOLDLEVELHEADERFLAG;
313 if (lev != styler.LevelAt(lineCurrent))
314 {
315 styler.SetLevel(lineCurrent, lev);
316 }
317 lineCurrent++;
318 levelCurrent = levelNext;
319 levelMinCurrent = levelCurrent;
320 visibleChars = 0;
321 }
322 if (!IsASpace(ch))
323 visibleChars++;
324 }
325
326
327 /*int endPos = startPos + length;
328
329 // Backtrack to previous line in case need to fix its fold status
330 int lineCurrent = styler.GetLine(startPos);
331 if (startPos > 0) {
332 if (lineCurrent > 0) {
333 lineCurrent--;
334 startPos = styler.LineStart(lineCurrent);
335 }
336 }
337 int spaceFlags = 0;
338 int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsComment);
339 char chNext = styler[startPos];
340 for (int i = startPos; i < endPos; i++) {
341 char ch = chNext;
342 chNext = styler.SafeGetCharAt(i + 1);
343
344 if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
345 int lev = indentCurrent;
346 int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsComment);
347 if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
348 // Only non whitespace lines can be headers
349 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
350 lev |= SC_FOLDLEVELHEADERFLAG;
351 } else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
352 // Line after is blank so check the next - maybe should continue further?
353 int spaceFlags2 = 0;
354 int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsComment);
355 if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
356 lev |= SC_FOLDLEVELHEADERFLAG;
357 }
358 }
359 }
360 indentCurrent = indentNext;
361 styler.SetLevel(lineCurrent, lev);
362 lineCurrent++;
363 }
364 }*/
365}
366
367static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle,
368 WordList *keywordlists[], Accessor &styler) {
369 FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsMatlabComment);
370}
371
372static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle,
373 WordList *keywordlists[], Accessor &styler) {
374 FoldMatlabOctaveDoc(startPos, length, initStyle, keywordlists, styler, IsOctaveComment);
375}
376
377
378static const char * const matlabWordListDesc[] = {
379 "Keywords",
380 0
381};
382
383static const char * const octaveWordListDesc[] = {
384 "Keywords",
385 0
386};
387
389
static bool IsAWordChar(const int ch)
Definition: LexMatlab.cxx:51
static const char *const octaveWordListDesc[]
Definition: LexMatlab.cxx:383
static bool IsMatlabComment(Accessor &styler, int pos, int len)
Definition: LexMatlab.cxx:43
static void FoldOctaveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
Definition: LexMatlab.cxx:372
static const char *const matlabWordListDesc[]
Definition: LexMatlab.cxx:378
static void ColouriseOctaveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
Definition: LexMatlab.cxx:206
static bool IsOctaveCommentChar(int c)
Definition: LexMatlab.cxx:39
static void ColouriseMatlabDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
Definition: LexMatlab.cxx:201
static bool IsMatlabCommentChar(int c)
Definition: LexMatlab.cxx:35
LexerModule lmMatlab(SCLEX_MATLAB, ColouriseMatlabDoc, "matlab", FoldMatlabDoc, matlabWordListDesc)
static void FoldMatlabOctaveDoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler, bool(*IsComment)(Accessor &, int, int))
Definition: LexMatlab.cxx:211
static int GetParenthesesCount(unsigned int startPos, Accessor &styler)
Definition: LexMatlab.cxx:62
static void FoldMatlabDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
Definition: LexMatlab.cxx:367
static bool IsOctaveComment(Accessor &styler, int pos, int len)
Definition: LexMatlab.cxx:47
static bool IsAWordStart(const int ch)
Definition: LexMatlab.cxx:55
static void ColouriseMatlabOctaveDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler, bool(*IsCommentChar)(int))
Definition: LexMatlab.cxx:79
LexerModule lmOctave(SCLEX_OCTAVE, ColouriseOctaveDoc, "octave", FoldOctaveDoc, octaveWordListDesc)
#define SCE_MATLAB_IDENTIFIER
Definition: SciLexer.h:616
#define SCE_MATLAB_NUMBER
Definition: SciLexer.h:612
#define SCE_MATLAB_COMMAND
Definition: SciLexer.h:611
#define SCLEX_MATLAB
Definition: SciLexer.h:47
#define SCE_MATLAB_DEFAULT
Definition: SciLexer.h:609
#define SCLEX_OCTAVE
Definition: SciLexer.h:69
#define SCE_MATLAB_FUNCTIONS
Definition: SciLexer.h:618
#define SCE_MATLAB_OPERATOR
Definition: SciLexer.h:615
#define SCE_MATLAB_KEYWORD
Definition: SciLexer.h:613
#define SCE_MATLAB_STRING
Definition: SciLexer.h:614
#define SCE_MATLAB_DOUBLEQUOTESTRING
Definition: SciLexer.h:617
#define SCE_MATLAB_COMMENT
Definition: SciLexer.h:610