Add an UI to enable/disable specific overlay handlers.
[TortoiseGit.git] / ext / scintilla / src / LexAPDL.cxx
bloba9a6c54072708cfeef06bac009ad9074e50f3ef8
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.
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include <stdio.h>
13 #include <stdarg.h>
15 #include "Platform.h"
17 #include "PropSet.h"
18 #include "Accessor.h"
19 #include "StyleContext.h"
20 #include "KeyWords.h"
21 #include "Scintilla.h"
22 #include "SciLexer.h"
24 #ifdef SCI_NAMESPACE
25 using namespace Scintilla;
26 #endif
28 static inline bool IsAWordChar(const int ch) {
29 return (ch < 0x80 && (isalnum(ch) || ch == '_'));
32 static inline bool IsAnOperator(char ch) {
33 // '.' left out as it is used to make up numbers
34 if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
35 ch == '(' || ch == ')' || ch == '=' || ch == '^' ||
36 ch == '[' || ch == ']' || ch == '<' || ch == '&' ||
37 ch == '>' || ch == ',' || ch == '|' || ch == '~' ||
38 ch == '$' || ch == ':' || ch == '%')
39 return true;
40 return false;
43 static void ColouriseAPDLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
44 Accessor &styler) {
46 int stringStart = ' ';
48 WordList &processors = *keywordlists[0];
49 WordList &commands = *keywordlists[1];
50 WordList &slashcommands = *keywordlists[2];
51 WordList &starcommands = *keywordlists[3];
52 WordList &arguments = *keywordlists[4];
53 WordList &functions = *keywordlists[5];
55 // Do not leak onto next line
56 initStyle = SCE_APDL_DEFAULT;
57 StyleContext sc(startPos, length, initStyle, styler);
59 for (; sc.More(); sc.Forward()) {
60 // Determine if the current state should terminate.
61 if (sc.state == SCE_APDL_NUMBER) {
62 if (!(IsADigit(sc.ch) || sc.ch == '.' || (sc.ch == 'e' || sc.ch == 'E') ||
63 ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
64 sc.SetState(SCE_APDL_DEFAULT);
66 } else if (sc.state == SCE_APDL_COMMENT) {
67 if (sc.atLineEnd) {
68 sc.SetState(SCE_APDL_DEFAULT);
70 } else if (sc.state == SCE_APDL_COMMENTBLOCK) {
71 if (sc.atLineEnd) {
72 if (sc.ch == '\r') {
73 sc.Forward();
75 sc.ForwardSetState(SCE_APDL_DEFAULT);
77 } else if (sc.state == SCE_APDL_STRING) {
78 if (sc.atLineEnd) {
79 sc.SetState(SCE_APDL_DEFAULT);
80 } else if ((sc.ch == '\'' && stringStart == '\'') || (sc.ch == '\"' && stringStart == '\"')) {
81 sc.ForwardSetState(SCE_APDL_DEFAULT);
83 } else if (sc.state == SCE_APDL_WORD) {
84 if (!IsAWordChar(sc.ch)) {
85 char s[100];
86 sc.GetCurrentLowered(s, sizeof(s));
87 if (processors.InList(s)) {
88 sc.ChangeState(SCE_APDL_PROCESSOR);
89 } else if (slashcommands.InList(s)) {
90 sc.ChangeState(SCE_APDL_SLASHCOMMAND);
91 } else if (starcommands.InList(s)) {
92 sc.ChangeState(SCE_APDL_STARCOMMAND);
93 } else if (commands.InList(s)) {
94 sc.ChangeState(SCE_APDL_COMMAND);
95 } else if (arguments.InList(s)) {
96 sc.ChangeState(SCE_APDL_ARGUMENT);
97 } else if (functions.InList(s)) {
98 sc.ChangeState(SCE_APDL_FUNCTION);
100 sc.SetState(SCE_APDL_DEFAULT);
102 } else if (sc.state == SCE_APDL_OPERATOR) {
103 if (!IsAnOperator(static_cast<char>(sc.ch))) {
104 sc.SetState(SCE_APDL_DEFAULT);
108 // Determine if a new state should be entered.
109 if (sc.state == SCE_APDL_DEFAULT) {
110 if (sc.ch == '!' && sc.chNext == '!') {
111 sc.SetState(SCE_APDL_COMMENTBLOCK);
112 } else if (sc.ch == '!') {
113 sc.SetState(SCE_APDL_COMMENT);
114 } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
115 sc.SetState(SCE_APDL_NUMBER);
116 } else if (sc.ch == '\'' || sc.ch == '\"') {
117 sc.SetState(SCE_APDL_STRING);
118 stringStart = sc.ch;
119 } else if (IsAWordChar(sc.ch) || ((sc.ch == '*' || sc.ch == '/') && !isgraph(sc.chPrev))) {
120 sc.SetState(SCE_APDL_WORD);
121 } else if (IsAnOperator(static_cast<char>(sc.ch))) {
122 sc.SetState(SCE_APDL_OPERATOR);
126 sc.Complete();
129 //------------------------------------------------------------------------------
130 // 06-27-07 Sergio Lucato
131 // - Included code folding for Ansys APDL lexer
132 // - Copyied from LexBasic.cxx and modified for APDL
133 //------------------------------------------------------------------------------
135 /* Bits:
136 * 1 - whitespace
137 * 2 - operator
138 * 4 - identifier
139 * 8 - decimal digit
140 * 16 - hex digit
141 * 32 - bin digit
143 static int character_classification[128] =
145 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,
146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
147 1, 2, 0, 2, 2, 2, 2, 2, 2, 2, 6, 2, 2, 2, 10, 6,
148 60, 60, 28, 28, 28, 28, 28, 28, 28, 28, 2, 2, 2, 2, 2, 2,
149 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
150 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 4,
151 2, 20, 20, 20, 20, 20, 20, 4, 4, 4, 4, 4, 4, 4, 4, 4,
152 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 0
155 static bool IsSpace(int c) {
156 return c < 128 && (character_classification[c] & 1);
159 static bool IsIdentifier(int c) {
160 return c < 128 && (character_classification[c] & 4);
163 static int LowerCase(int c)
165 if (c >= 'A' && c <= 'Z')
166 return 'a' + c - 'A';
167 return c;
170 static int CheckAPDLFoldPoint(char const *token, int &level) {
171 if (!strcmp(token, "*if") ||
172 !strcmp(token, "*do") ||
173 !strcmp(token, "*dowhile") ) {
174 level |= SC_FOLDLEVELHEADERFLAG;
175 return 1;
177 if (!strcmp(token, "*endif") ||
178 !strcmp(token, "*enddo") ) {
179 return -1;
181 return 0;
184 static void FoldAPDLDoc(unsigned int startPos, int length, int,
185 WordList *[], Accessor &styler) {
187 int line = styler.GetLine(startPos);
188 int level = styler.LevelAt(line);
189 int go = 0, done = 0;
190 int endPos = startPos + length;
191 char word[256];
192 int wordlen = 0;
193 int i;
194 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
195 // Scan for tokens at the start of the line (they may include
196 // whitespace, for tokens like "End Function"
197 for (i = startPos; i < endPos; i++) {
198 int c = styler.SafeGetCharAt(i);
199 if (!done && !go) {
200 if (wordlen) { // are we scanning a token already?
201 word[wordlen] = static_cast<char>(LowerCase(c));
202 if (!IsIdentifier(c)) { // done with token
203 word[wordlen] = '\0';
204 go = CheckAPDLFoldPoint(word, level);
205 if (!go) {
206 // Treat any whitespace as single blank, for
207 // things like "End Function".
208 if (IsSpace(c) && IsIdentifier(word[wordlen - 1])) {
209 word[wordlen] = ' ';
210 if (wordlen < 255)
211 wordlen++;
213 else // done with this line
214 done = 1;
216 } else if (wordlen < 255) {
217 wordlen++;
219 } else { // start scanning at first non-whitespace character
220 if (!IsSpace(c)) {
221 if (IsIdentifier(c)) {
222 word[0] = static_cast<char>(LowerCase(c));
223 wordlen = 1;
224 } else // done with this line
225 done = 1;
229 if (c == '\n') { // line end
230 if (!done && wordlen == 0 && foldCompact) // line was only space
231 level |= SC_FOLDLEVELWHITEFLAG;
232 if (level != styler.LevelAt(line))
233 styler.SetLevel(line, level);
234 level += go;
235 line++;
236 // reset state
237 wordlen = 0;
238 level &= ~SC_FOLDLEVELHEADERFLAG;
239 level &= ~SC_FOLDLEVELWHITEFLAG;
240 go = 0;
241 done = 0;
246 static const char * const apdlWordListDesc[] = {
247 "processors",
248 "commands",
249 "slashommands",
250 "starcommands",
251 "arguments",
252 "functions",
256 LexerModule lmAPDL(SCLEX_APDL, ColouriseAPDLDoc, "apdl", FoldAPDLDoc, apdlWordListDesc);