~ubuntu-branches/ubuntu/wily/geany/wily

« back to all changes in this revision

Viewing changes to scintilla/lexers/LexVerilog.cxx

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-12-10 07:43:26 UTC
  • mfrom: (3.3.7 sid)
  • Revision ID: package-import@ubuntu.com-20111210074326-s8yqbew5i20h33tf
Tags: 0.21-1ubuntu1
* Merge from Debian Unstable, remaining changes:
  - debian/patches/20_use_evince_viewer.patch:
     + use evince as viewer for pdf and dvi files
  - debian/patches/20_use_x_terminal_emulator.patch:
     + use x-terminal-emulator as terminal
  - debian/control
     + Add breaks on geany-plugins-common << 0.20
* Also fixes bugs:
  - Filter for MATLAB/Octave files filters everythign (LP: 885505)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Scintilla source code edit control
 
2
/** @file LexVerilog.cxx
 
3
 ** Lexer for Verilog.
 
4
 ** Written by Avi Yegudin, based on C++ lexer by Neil Hodgson
 
5
 **/
 
6
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
 
7
// The License.txt file describes the conditions under which this software may be distributed.
 
8
 
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
#include <stdio.h>
 
12
#include <stdarg.h>
 
13
#include <assert.h>
 
14
#include <ctype.h>
 
15
 
 
16
#include "ILexer.h"
 
17
#include "Scintilla.h"
 
18
#include "SciLexer.h"
 
19
 
 
20
#include "WordList.h"
 
21
#include "LexAccessor.h"
 
22
#include "Accessor.h"
 
23
#include "StyleContext.h"
 
24
#include "CharacterSet.h"
 
25
#include "LexerModule.h"
 
26
 
 
27
#ifdef SCI_NAMESPACE
 
28
using namespace Scintilla;
 
29
#endif
 
30
 
 
31
static inline bool IsAWordChar(const int ch) {
 
32
        return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' || ch == '\'');
 
33
}
 
34
 
 
35
static inline bool IsAWordStart(const int ch) {
 
36
        return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '$');
 
37
}
 
38
 
 
39
static void ColouriseVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
 
40
                            Accessor &styler) {
 
41
 
 
42
        WordList &keywords = *keywordlists[0];
 
43
        WordList &keywords2 = *keywordlists[1];
 
44
        WordList &keywords3 = *keywordlists[2];
 
45
        WordList &keywords4 = *keywordlists[3];
 
46
 
 
47
        // Do not leak onto next line
 
48
        if (initStyle == SCE_V_STRINGEOL)
 
49
                initStyle = SCE_V_DEFAULT;
 
50
 
 
51
        StyleContext sc(startPos, length, initStyle, styler);
 
52
 
 
53
        for (; sc.More(); sc.Forward()) {
 
54
 
 
55
                if (sc.atLineStart && (sc.state == SCE_V_STRING)) {
 
56
                        // Prevent SCE_V_STRINGEOL from leaking back to previous line
 
57
                        sc.SetState(SCE_V_STRING);
 
58
                }
 
59
 
 
60
                // Handle line continuation generically.
 
61
                if (sc.ch == '\\') {
 
62
                        if (sc.chNext == '\n' || sc.chNext == '\r') {
 
63
                                sc.Forward();
 
64
                                if (sc.ch == '\r' && sc.chNext == '\n') {
 
65
                                        sc.Forward();
 
66
                                }
 
67
                                continue;
 
68
                        }
 
69
                }
 
70
 
 
71
                // Determine if the current state should terminate.
 
72
                if (sc.state == SCE_V_OPERATOR) {
 
73
                        sc.SetState(SCE_V_DEFAULT);
 
74
                } else if (sc.state == SCE_V_NUMBER) {
 
75
                        if (!IsAWordChar(sc.ch)) {
 
76
                                sc.SetState(SCE_V_DEFAULT);
 
77
                        }
 
78
                } else if (sc.state == SCE_V_IDENTIFIER) {
 
79
                        if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
 
80
                                char s[100];
 
81
                                sc.GetCurrent(s, sizeof(s));
 
82
                                if (keywords.InList(s)) {
 
83
                                        sc.ChangeState(SCE_V_WORD);
 
84
                                } else if (keywords2.InList(s)) {
 
85
                                        sc.ChangeState(SCE_V_WORD2);
 
86
                                } else if (keywords3.InList(s)) {
 
87
                                        sc.ChangeState(SCE_V_WORD3);
 
88
                                } else if (keywords4.InList(s)) {
 
89
                                        sc.ChangeState(SCE_V_USER);
 
90
                                }
 
91
                                sc.SetState(SCE_V_DEFAULT);
 
92
                        }
 
93
                } else if (sc.state == SCE_V_PREPROCESSOR) {
 
94
                        if (!IsAWordChar(sc.ch)) {
 
95
                                sc.SetState(SCE_V_DEFAULT);
 
96
                        }
 
97
                } else if (sc.state == SCE_V_COMMENT) {
 
98
                        if (sc.Match('*', '/')) {
 
99
                                sc.Forward();
 
100
                                sc.ForwardSetState(SCE_V_DEFAULT);
 
101
                        }
 
102
                } else if (sc.state == SCE_V_COMMENTLINE || sc.state == SCE_V_COMMENTLINEBANG) {
 
103
                        if (sc.atLineStart) {
 
104
                                sc.SetState(SCE_V_DEFAULT);
 
105
                        }
 
106
                } else if (sc.state == SCE_V_STRING) {
 
107
                        if (sc.ch == '\\') {
 
108
                                if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
 
109
                                        sc.Forward();
 
110
                                }
 
111
                        } else if (sc.ch == '\"') {
 
112
                                sc.ForwardSetState(SCE_V_DEFAULT);
 
113
                        } else if (sc.atLineEnd) {
 
114
                                sc.ChangeState(SCE_V_STRINGEOL);
 
115
                                sc.ForwardSetState(SCE_V_DEFAULT);
 
116
                        }
 
117
                }
 
118
 
 
119
                // Determine if a new state should be entered.
 
120
                if (sc.state == SCE_V_DEFAULT) {
 
121
                        if (IsADigit(sc.ch) || (sc.ch == '\'') || (sc.ch == '.' && IsADigit(sc.chNext))) {
 
122
                                sc.SetState(SCE_V_NUMBER);
 
123
                        } else if (IsAWordStart(sc.ch)) {
 
124
                                sc.SetState(SCE_V_IDENTIFIER);
 
125
                        } else if (sc.Match('/', '*')) {
 
126
                                sc.SetState(SCE_V_COMMENT);
 
127
                                sc.Forward();   // Eat the * so it isn't used for the end of the comment
 
128
                        } else if (sc.Match('/', '/')) {
 
129
                                if (sc.Match("//!"))    // Nice to have a different comment style
 
130
                                        sc.SetState(SCE_V_COMMENTLINEBANG);
 
131
                                else
 
132
                                        sc.SetState(SCE_V_COMMENTLINE);
 
133
                        } else if (sc.ch == '\"') {
 
134
                                sc.SetState(SCE_V_STRING);
 
135
                        } else if (sc.ch == '`') {
 
136
                                sc.SetState(SCE_V_PREPROCESSOR);
 
137
                                // Skip whitespace between ` and preprocessor word
 
138
                                do {
 
139
                                        sc.Forward();
 
140
                                } while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
 
141
                                if (sc.atLineEnd) {
 
142
                                        sc.SetState(SCE_V_DEFAULT);
 
143
                                }
 
144
                        } else if (isoperator(static_cast<char>(sc.ch)) || sc.ch == '@' || sc.ch == '#') {
 
145
                                sc.SetState(SCE_V_OPERATOR);
 
146
                        }
 
147
                }
 
148
        }
 
149
        sc.Complete();
 
150
}
 
151
 
 
152
static bool IsStreamCommentStyle(int style) {
 
153
        return style == SCE_V_COMMENT;
 
154
}
 
155
 
 
156
static bool IsCommentLine(int line, Accessor &styler) {
 
157
        int pos = styler.LineStart(line);
 
158
        int eolPos = styler.LineStart(line + 1) - 1;
 
159
        for (int i = pos; i < eolPos; i++) {
 
160
                char ch = styler[i];
 
161
                char chNext = styler.SafeGetCharAt(i + 1);
 
162
                int style = styler.StyleAt(i);
 
163
                if (ch == '/' && chNext == '/' &&
 
164
                   (style == SCE_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG)) {
 
165
                        return true;
 
166
                } else if (!IsASpaceOrTab(ch)) {
 
167
                        return false;
 
168
                }
 
169
        }
 
170
        return false;
 
171
}
 
172
// Store both the current line's fold level and the next lines in the
 
173
// level store to make it easy to pick up with each increment
 
174
// and to make it possible to fiddle the current level for "} else {".
 
175
static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle,
 
176
                            Accessor &styler) {
 
177
        bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
 
178
        bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
 
179
        bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
 
180
        bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
 
181
        // Verilog specific folding options:
 
182
        // fold_at_module -
 
183
        //      Generally used methodology in verilog code is
 
184
        //      one module per file, so folding at module definition is useless.
 
185
        // fold_at_brace/parenthese -
 
186
        //      Folding of long port lists can be convenient.
 
187
        bool foldAtModule = styler.GetPropertyInt("fold.verilog.flags", 0) != 0;
 
188
        bool foldAtBrace  = 1;
 
189
        bool foldAtParenthese  = 1;
 
190
 
 
191
        unsigned int endPos = startPos + length;
 
192
        int visibleChars = 0;
 
193
        int lineCurrent = styler.GetLine(startPos);
 
194
        int levelCurrent = SC_FOLDLEVELBASE;
 
195
        if (lineCurrent > 0)
 
196
                levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
 
197
        int levelMinCurrent = levelCurrent;
 
198
        int levelNext = levelCurrent;
 
199
        char chNext = styler[startPos];
 
200
        int styleNext = styler.StyleAt(startPos);
 
201
        int style = initStyle;
 
202
        for (unsigned int i = startPos; i < endPos; i++) {
 
203
                char ch = chNext;
 
204
                chNext = styler.SafeGetCharAt(i + 1);
 
205
                int stylePrev = style;
 
206
                style = styleNext;
 
207
                styleNext = styler.StyleAt(i + 1);
 
208
                bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
 
209
                if (foldComment && IsStreamCommentStyle(style)) {
 
210
                        if (!IsStreamCommentStyle(stylePrev)) {
 
211
                                levelNext++;
 
212
                        } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
 
213
                                // Comments don't end at end of line and the next character may be unstyled.
 
214
                                levelNext--;
 
215
                        }
 
216
                }
 
217
                if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
 
218
                {
 
219
                        if (!IsCommentLine(lineCurrent - 1, styler)
 
220
                            && IsCommentLine(lineCurrent + 1, styler))
 
221
                                levelNext++;
 
222
                        else if (IsCommentLine(lineCurrent - 1, styler)
 
223
                                 && !IsCommentLine(lineCurrent+1, styler))
 
224
                                levelNext--;
 
225
                }
 
226
                if (foldComment && (style == SCE_V_COMMENTLINE)) {
 
227
                        if ((ch == '/') && (chNext == '/')) {
 
228
                                char chNext2 = styler.SafeGetCharAt(i + 2);
 
229
                                if (chNext2 == '{') {
 
230
                                        levelNext++;
 
231
                                } else if (chNext2 == '}') {
 
232
                                        levelNext--;
 
233
                                }
 
234
                        }
 
235
                }
 
236
                if (foldPreprocessor && (style == SCE_V_PREPROCESSOR)) {
 
237
                        if (ch == '`') {
 
238
                                unsigned int j = i + 1;
 
239
                                while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
 
240
                                        j++;
 
241
                                }
 
242
                                if (styler.Match(j, "if")) {
 
243
                                        levelNext++;
 
244
                                } else if (styler.Match(j, "end")) {
 
245
                                        levelNext--;
 
246
                                }
 
247
                        }
 
248
                }
 
249
                if (style == SCE_V_OPERATOR) {
 
250
                    if (foldAtParenthese) {
 
251
                        if (ch == '(') {
 
252
                                levelNext++;
 
253
                        } else if (ch == ')') {
 
254
                                levelNext--;
 
255
                        }
 
256
                    }
 
257
                }
 
258
                if (style == SCE_V_OPERATOR) {
 
259
                    if (foldAtBrace) {
 
260
                        if (ch == '{') {
 
261
                                levelNext++;
 
262
                        } else if (ch == '}') {
 
263
                                levelNext--;
 
264
                        }
 
265
                    }
 
266
                }
 
267
                if (style == SCE_V_WORD && stylePrev != SCE_V_WORD) {
 
268
                        unsigned int j = i;
 
269
                        if (styler.Match(j, "case") ||
 
270
                            styler.Match(j, "casex") ||
 
271
                            styler.Match(j, "casez") ||
 
272
                            styler.Match(j, "function") ||
 
273
                            styler.Match(j, "fork") ||
 
274
                            styler.Match(j, "table") ||
 
275
                            styler.Match(j, "task") ||
 
276
                            styler.Match(j, "generate") ||
 
277
                            styler.Match(j, "specify") ||
 
278
                            styler.Match(j, "primitive") ||
 
279
                            (styler.Match(j, "module") && foldAtModule) ||
 
280
                            styler.Match(j, "begin")) {
 
281
                                levelNext++;
 
282
                        } else if (styler.Match(j, "endcase") ||
 
283
                                   styler.Match(j, "endfunction") ||
 
284
                                   styler.Match(j, "join") ||
 
285
                                   styler.Match(j, "endtask") ||
 
286
                                   styler.Match(j, "endgenerate") ||
 
287
                                   styler.Match(j, "endtable") ||
 
288
                                   styler.Match(j, "endspecify") ||
 
289
                                   styler.Match(j, "endprimitive") ||
 
290
                                   (styler.Match(j, "endmodule") && foldAtModule) ||
 
291
                                   (styler.Match(j, "end") && !IsAWordChar(styler.SafeGetCharAt(j+3)))) {
 
292
                                levelNext--;
 
293
                        }
 
294
                }
 
295
                if (atEOL) {
 
296
                        int levelUse = levelCurrent;
 
297
                        if (foldAtElse) {
 
298
                                levelUse = levelMinCurrent;
 
299
                        }
 
300
                        int lev = levelUse | levelNext << 16;
 
301
                        if (visibleChars == 0 && foldCompact)
 
302
                                lev |= SC_FOLDLEVELWHITEFLAG;
 
303
                        if (levelUse < levelNext)
 
304
                                lev |= SC_FOLDLEVELHEADERFLAG;
 
305
                        if (lev != styler.LevelAt(lineCurrent)) {
 
306
                                styler.SetLevel(lineCurrent, lev);
 
307
                        }
 
308
                        lineCurrent++;
 
309
                        levelCurrent = levelNext;
 
310
                        levelMinCurrent = levelCurrent;
 
311
                        visibleChars = 0;
 
312
                }
 
313
                if (!isspacechar(ch))
 
314
                        visibleChars++;
 
315
        }
 
316
}
 
317
 
 
318
static void FoldVerilogDoc(unsigned int startPos, int length, int initStyle, WordList *[],
 
319
                       Accessor &styler) {
 
320
        FoldNoBoxVerilogDoc(startPos, length, initStyle, styler);
 
321
}
 
322
 
 
323
static const char * const verilogWordLists[] = {
 
324
            "Primary keywords and identifiers",
 
325
            "Secondary keywords and identifiers",
 
326
            "System Tasks",
 
327
            "User defined tasks and identifiers",
 
328
            "Unused",
 
329
            0,
 
330
        };
 
331
 
 
332
 
 
333
LexerModule lmVerilog(SCLEX_VERILOG, ColouriseVerilogDoc, "verilog", FoldVerilogDoc, verilogWordLists);