scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
[anjuta-extras.git] / plugins / scintilla / scintilla / LexSpice.cxx
blobcb1e6582886e7d392223d7c5d3338cd64d3a1660
1 // Scintilla source code edit control
2 /** @file LexSpice.cxx
3 ** Lexer for Spice
4 **/
5 // Copyright 2006 by Fabien Proriol
6 // The License.txt file describes the conditions under which this software may be distributed.
8 #include <stdlib.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <stdarg.h>
12 #include <assert.h>
14 #include <string>
16 #include "ILexer.h"
17 #include "Scintilla.h"
18 #include "SciLexer.h"
20 #include "WordList.h"
21 #include "LexAccessor.h"
22 #include "Accessor.h"
23 #include "StyleContext.h"
24 #include "CharacterSet.h"
25 #include "LexerModule.h"
27 #ifdef SCI_NAMESPACE
28 using namespace Scintilla;
29 #endif
32 * Interface
35 static void ColouriseDocument(
36 unsigned int startPos,
37 int length,
38 int initStyle,
39 WordList *keywordlists[],
40 Accessor &styler);
42 static const char * const spiceWordListDesc[] = {
43 "Keywords", // SPICE command
44 "Keywords2", // SPICE functions
45 "Keywords3", // SPICE params
49 LexerModule lmSpice(SCLEX_SPICE, ColouriseDocument, "spice", NULL, spiceWordListDesc);
52 * Implementation
55 static void ColouriseComment(StyleContext& sc, bool& apostropheStartsAttribute);
56 static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute);
57 static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute);
58 static void ColouriseWhiteSpace(StyleContext& sc, bool& apostropheStartsAttribute);
59 static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute);
61 static inline bool IsDelimiterCharacter(int ch);
62 static inline bool IsNumberStartCharacter(int ch);
63 static inline bool IsNumberCharacter(int ch);
64 static inline bool IsSeparatorOrDelimiterCharacter(int ch);
65 static inline bool IsWordStartCharacter(int ch);
66 static inline bool IsWordCharacter(int ch);
68 static void ColouriseComment(StyleContext& sc, bool&) {
69 sc.SetState(SCE_SPICE_COMMENTLINE);
70 while (!sc.atLineEnd) {
71 sc.Forward();
75 static void ColouriseDelimiter(StyleContext& sc, bool& apostropheStartsAttribute) {
76 apostropheStartsAttribute = sc.Match (')');
77 sc.SetState(SCE_SPICE_DELIMITER);
78 sc.ForwardSetState(SCE_SPICE_DEFAULT);
81 static void ColouriseNumber(StyleContext& sc, bool& apostropheStartsAttribute) {
82 apostropheStartsAttribute = true;
83 std::string number;
84 sc.SetState(SCE_SPICE_NUMBER);
85 // Get all characters up to a delimiter or a separator, including points, but excluding
86 // double points (ranges).
87 while (!IsSeparatorOrDelimiterCharacter(sc.ch) || (sc.ch == '.' && sc.chNext != '.')) {
88 number += static_cast<char>(sc.ch);
89 sc.Forward();
91 // Special case: exponent with sign
92 if ((sc.chPrev == 'e' || sc.chPrev == 'E') &&
93 (sc.ch == '+' || sc.ch == '-')) {
94 number += static_cast<char>(sc.ch);
95 sc.Forward ();
96 while (!IsSeparatorOrDelimiterCharacter(sc.ch)) {
97 number += static_cast<char>(sc.ch);
98 sc.Forward();
101 sc.SetState(SCE_SPICE_DEFAULT);
104 static void ColouriseWhiteSpace(StyleContext& sc, bool& ) {
105 sc.SetState(SCE_SPICE_DEFAULT);
106 sc.ForwardSetState(SCE_SPICE_DEFAULT);
109 static void ColouriseWord(StyleContext& sc, WordList& keywords, WordList& keywords2, WordList& keywords3, bool& apostropheStartsAttribute) {
110 apostropheStartsAttribute = true;
111 sc.SetState(SCE_SPICE_IDENTIFIER);
112 std::string word;
113 while (!sc.atLineEnd && !IsSeparatorOrDelimiterCharacter(sc.ch)) {
114 word += static_cast<char>(tolower(sc.ch));
115 sc.Forward();
117 if (keywords.InList(word.c_str())) {
118 sc.ChangeState(SCE_SPICE_KEYWORD);
119 if (word != "all") {
120 apostropheStartsAttribute = false;
123 else if (keywords2.InList(word.c_str())) {
124 sc.ChangeState(SCE_SPICE_KEYWORD2);
125 if (word != "all") {
126 apostropheStartsAttribute = false;
129 else if (keywords3.InList(word.c_str())) {
130 sc.ChangeState(SCE_SPICE_KEYWORD3);
131 if (word != "all") {
132 apostropheStartsAttribute = false;
135 sc.SetState(SCE_SPICE_DEFAULT);
139 // ColouriseDocument
141 static void ColouriseDocument(
142 unsigned int startPos,
143 int length,
144 int initStyle,
145 WordList *keywordlists[],
146 Accessor &styler) {
147 WordList &keywords = *keywordlists[0];
148 WordList &keywords2 = *keywordlists[1];
149 WordList &keywords3 = *keywordlists[2];
150 StyleContext sc(startPos, length, initStyle, styler);
151 int lineCurrent = styler.GetLine(startPos);
152 bool apostropheStartsAttribute = (styler.GetLineState(lineCurrent) & 1) != 0;
153 while (sc.More()) {
154 if (sc.atLineEnd) {
155 // Go to the next line
156 sc.Forward();
157 lineCurrent++;
158 // Remember the line state for future incremental lexing
159 styler.SetLineState(lineCurrent, apostropheStartsAttribute);
160 // Don't continue any styles on the next line
161 sc.SetState(SCE_SPICE_DEFAULT);
163 // Comments
164 if ((sc.Match('*') && sc.atLineStart) || sc.Match('*','~')) {
165 ColouriseComment(sc, apostropheStartsAttribute);
166 // Whitespace
167 } else if (IsASpace(sc.ch)) {
168 ColouriseWhiteSpace(sc, apostropheStartsAttribute);
169 // Delimiters
170 } else if (IsDelimiterCharacter(sc.ch)) {
171 ColouriseDelimiter(sc, apostropheStartsAttribute);
172 // Numbers
173 } else if (IsADigit(sc.ch) || sc.ch == '#') {
174 ColouriseNumber(sc, apostropheStartsAttribute);
175 // Keywords or identifiers
176 } else {
177 ColouriseWord(sc, keywords, keywords2, keywords3, apostropheStartsAttribute);
180 sc.Complete();
183 static inline bool IsDelimiterCharacter(int ch) {
184 switch (ch) {
185 case '&':
186 case '\'':
187 case '(':
188 case ')':
189 case '*':
190 case '+':
191 case ',':
192 case '-':
193 case '.':
194 case '/':
195 case ':':
196 case ';':
197 case '<':
198 case '=':
199 case '>':
200 case '|':
201 return true;
202 default:
203 return false;
207 static inline bool IsNumberCharacter(int ch) {
208 return IsNumberStartCharacter(ch) ||
209 ch == '_' ||
210 ch == '.' ||
211 ch == '#' ||
212 (ch >= 'a' && ch <= 'f') ||
213 (ch >= 'A' && ch <= 'F');
216 static inline bool IsNumberStartCharacter(int ch) {
217 return IsADigit(ch);
220 static inline bool IsSeparatorOrDelimiterCharacter(int ch) {
221 return IsASpace(ch) || IsDelimiterCharacter(ch);
224 static inline bool IsWordCharacter(int ch) {
225 return IsWordStartCharacter(ch) || IsADigit(ch);
228 static inline bool IsWordStartCharacter(int ch) {
229 return (isascii(ch) && isalpha(ch)) || ch == '_';