]> git.saurik.com Git - wxWidgets.git/blame - src/stc/scintilla/lexers/LexAPDL.cxx
wxMessageBox off the main thread lost result code.
[wxWidgets.git] / src / stc / scintilla / lexers / LexAPDL.cxx
CommitLineData
a33203cb
RD
1// Scintilla source code edit control
2/** @file LexAPDL.cxx
3 ** Lexer for APDL. Based on the lexer for Assembler by The Black Horus.
4 ** By Hadar Raz.
5 **/
6// Copyright 1998-2003 by Neil Hodgson <neilh@scintilla.org>
7// The License.txt file describes the conditions under which this software may be distributed.
591d01be
RD
8
9#include <stdlib.h>
10#include <string.h>
591d01be
RD
11#include <stdio.h>
12#include <stdarg.h>
1dcf666d
RD
13#include <assert.h>
14#include <ctype.h>
591d01be 15
1dcf666d
RD
16#include "ILexer.h"
17#include "Scintilla.h"
18#include "SciLexer.h"
591d01be 19
1dcf666d
RD
20#include "WordList.h"
21#include "LexAccessor.h"
591d01be
RD
22#include "Accessor.h"
23#include "StyleContext.h"
1dcf666d
RD
24#include "CharacterSet.h"
25#include "LexerModule.h"
591d01be 26
7e0c58e9
RD
27#ifdef SCI_NAMESPACE
28using namespace Scintilla;
29#endif
591d01be
RD
30
31static inline bool IsAWordChar(const int ch) {
a33203cb 32 return (ch < 0x80 && (isalnum(ch) || ch == '_'));
591d01be
RD
33}
34
a33203cb
RD
35static inline bool IsAnOperator(char ch) {
36 // '.' left out as it is used to make up numbers
37 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
38 ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
39 ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
40 ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
41 ch == '$' || ch == ':' || ch == '%')
42 return true;
43 return false;
591d01be
RD
44}
45
a33203cb
RD
46static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
47 Accessor &styler) {
48
49 int stringStart = ' ';
50
51 WordList &processors = *keywordlists[0];
52 WordList &commands = *keywordlists[1];
53 WordList &slashcommands = *keywordlists[2];
54 WordList &starcommands = *keywordlists[3];
55 WordList &arguments = *keywordlists[4];
56 WordList &functions = *keywordlists[5];
57
58 // Do not leak onto next line
59 initStyle = SCE_APDL_DEFAULT;
60 StyleContext sc(startPos, length, initStyle, styler);
61
62 for (; sc.More(); sc.Forward()) {
63 // Determine if the current state should terminate.
64 if (sc.state == SCE_APDL_NUMBER) {
65 if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
66 ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
67 sc.SetState(SCE_APDL_DEFAULT);
68 }
69 } else if (sc.state == SCE_APDL_COMMENT) {
70 if (sc.atLineEnd) {
71 sc.SetState(SCE_APDL_DEFAULT);
72 }
73 } else if (sc.state == SCE_APDL_COMMENTBLOCK) {
74 if (sc.atLineEnd) {
75 if (sc.ch == '\r') {
76 sc.Forward();
77 }
78 sc.ForwardSetState(SCE_APDL_DEFAULT);
79 }
80 } else if (sc.state == SCE_APDL_STRING) {
81 if (sc.atLineEnd) {
82 sc.SetState(SCE_APDL_DEFAULT);
83 } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
84 sc.ForwardSetState(SCE_APDL_DEFAULT);
85 }
86 } else if (sc.state == SCE_APDL_WORD) {
87 if (!IsAWordChar(sc.ch)) {
88 char s[100];
89 sc.GetCurrentLowered(s, sizeof(s));
90 if (processors.InList(s)) {
91 sc.ChangeState(SCE_APDL_PROCESSOR);
92 } else if (slashcommands.InList(s)) {
93 sc.ChangeState(SCE_APDL_SLASHCOMMAND);
94 } else if (starcommands.InList(s)) {
95 sc.ChangeState(SCE_APDL_STARCOMMAND);
96 } else if (commands.InList(s)) {
97 sc.ChangeState(SCE_APDL_COMMAND);
98 } else if (arguments.InList(s)) {
99 sc.ChangeState(SCE_APDL_ARGUMENT);
100 } else if (functions.InList(s)) {
101 sc.ChangeState(SCE_APDL_FUNCTION);
102 }
103 sc.SetState(SCE_APDL_DEFAULT);
104 }
105 } else if (sc.state == SCE_APDL_OPERATOR) {
106 if (!IsAnOperator(static_cast<char>(sc.ch))) {
107 sc.SetState(SCE_APDL_DEFAULT);
108 }
109 }
110
111 // Determine if a new state should be entered.
112 if (sc.state == SCE_APDL_DEFAULT) {
113 if (sc.ch == '!' && sc.chNext == '!') {
114 sc.SetState(SCE_APDL_COMMENTBLOCK);
115 } else if (sc.ch == '!') {
116 sc.SetState(SCE_APDL_COMMENT);
117 } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
118 sc.SetState(SCE_APDL_NUMBER);
119 } else if (sc.ch == '\'' || sc.ch == '\"') {
120 sc.SetState(SCE_APDL_STRING);
121 stringStart = sc.ch;
122 } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
123 sc.SetState(SCE_APDL_WORD);
124 } else if (IsAnOperator(static_cast<char>(sc.ch))) {
125 sc.SetState(SCE_APDL_OPERATOR);
126 }
127 }
128 }
129 sc.Complete();
591d01be
RD
130}
131
7e0c58e9
RD
132//------------------------------------------------------------------------------
133// 06-27-07 Sergio Lucato
134// - Included code folding for Ansys APDL lexer
135// - Copyied from LexBasic.cxx and modified for APDL
136//------------------------------------------------------------------------------
137
138/* Bits:
139 * 1 - whitespace
140 * 2 - operator
141 * 4 - identifier
142 * 8 - decimal digit
143 * 16 - hex digit
144 * 32 - bin digit
145 */
146static int character_classification[128] =
147{
148 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
150 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
151 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
152 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
153 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
154 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
155 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
156};
157
158static bool IsSpace(int c) {
159 return c < 128 && (character_classification[c] & 1);
160}
161
162static bool IsIdentifier(int c) {
163 return c < 128 && (character_classification[c] & 4);
164}
165
166static int LowerCase(int c)
167{
168 if (c >= 'A' && c <= 'Z')
169 return 'a' + c - 'A';
170 return c;
171}
172
173static int CheckAPDLFoldPoint(char const *token, int &level) {
174 if (!strcmp(token, "*if") ||
175 !strcmp(token, "*do") ||
176 !strcmp(token, "*dowhile") ) {
177 level |= SC_FOLDLEVELHEADERFLAG;
178 return 1;
179 }
180 if (!strcmp(token, "*endif") ||
181 !strcmp(token, "*enddo") ) {
182 return -1;
183 }
184 return 0;
185}
186
187static void FoldAPDLDoc(unsigned int startPos, int length, int,
188 WordList *[], Accessor &styler) {
189
190 int line = styler.GetLine(startPos);
191 int level = styler.LevelAt(line);
192 int go = 0, done = 0;
193 int endPos = startPos + length;
194 char word[256];
195 int wordlen = 0;
196 int i;
197 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
198 // Scan for tokens at the start of the line (they may include
199 // whitespace, for tokens like "End Function"
200 for (i = startPos; i < endPos; i++) {
201 int c = styler.SafeGetCharAt(i);
202 if (!done && !go) {
203 if (wordlen) { // are we scanning a token already?
204 word[wordlen] = static_cast<char>(LowerCase(c));
205 if (!IsIdentifier(c)) { // done with token
206 word[wordlen] = '\0';
207 go = CheckAPDLFoldPoint(word, level);
208 if (!go) {
209 // Treat any whitespace as single blank, for
210 // things like "End Function".
211 if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
212 word[wordlen] = ' ';
213 if (wordlen < 255)
214 wordlen++;
215 }
216 else // done with this line
217 done = 1;
218 }
219 } else if (wordlen < 255) {
220 wordlen++;
221 }
222 } else { // start scanning at first non-whitespace character
223 if (!IsSpace(c)) {
224 if (IsIdentifier(c)) {
225 word[0] = static_cast<char>(LowerCase(c));
226 wordlen = 1;
227 } else // done with this line
228 done = 1;
229 }
230 }
231 }
232 if (c == '\n') { // line end
233 if (!done && wordlen == 0 && foldCompact) // line was only space
234 level |= SC_FOLDLEVELWHITEFLAG;
235 if (level != styler.LevelAt(line))
236 styler.SetLevel(line, level);
237 level += go;
238 line++;
239 // reset state
240 wordlen = 0;
241 level &= ~SC_FOLDLEVELHEADERFLAG;
242 level &= ~SC_FOLDLEVELWHITEFLAG;
243 go = 0;
244 done = 0;
245 }
246 }
247}
248
591d01be 249static const char * const apdlWordListDesc[] = {
a33203cb
RD
250 "processors",
251 "commands",
252 "slashommands",
253 "starcommands",
254 "arguments",
255 "functions",
591d01be
RD
256 0
257};
258
7e0c58e9 259LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);