Fixed issue #2175: TortoiseGitBlame fails to search if line has non-ascii chars and...
[TortoiseGit.git] / ext / scintilla / lexers / LexPLM.cxx
blob8574ebfa8a007d7812465f6c61fef24d50e9e32c
1 // Copyright (c) 1990-2007, Scientific Toolworks, Inc.
2 // Author: Jason Haslam
3 // The License.txt file describes the conditions under which this software may be distributed.
5 #include <stdlib.h>
6 #include <string.h>
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <assert.h>
10 #include <ctype.h>
12 #include "ILexer.h"
13 #include "Scintilla.h"
14 #include "SciLexer.h"
16 #include "WordList.h"
17 #include "LexAccessor.h"
18 #include "Accessor.h"
19 #include "StyleContext.h"
20 #include "CharacterSet.h"
21 #include "LexerModule.h"
23 #ifdef SCI_NAMESPACE
24 using namespace Scintilla;
25 #endif
27 static void GetRange(unsigned int start,
28 unsigned int end,
29 Accessor &styler,
30 char *s,
31 unsigned int len) {
32 unsigned int i = 0;
33 while ((i < end - start + 1) && (i < len-1)) {
34 s[i] = static_cast<char>(tolower(styler[start + i]));
35 i++;
37 s[i] = '\0';
40 static void ColourisePlmDoc(unsigned int startPos,
41 int length,
42 int initStyle,
43 WordList *keywordlists[],
44 Accessor &styler)
46 unsigned int endPos = startPos + length;
47 int state = initStyle;
49 styler.StartAt(startPos);
50 styler.StartSegment(startPos);
52 for (unsigned int i = startPos; i < endPos; i++) {
53 char ch = styler.SafeGetCharAt(i);
54 char chNext = styler.SafeGetCharAt(i + 1);
56 if (state == SCE_PLM_DEFAULT) {
57 if (ch == '/' && chNext == '*') {
58 styler.ColourTo(i - 1, state);
59 state = SCE_PLM_COMMENT;
60 } else if (ch == '\'') {
61 styler.ColourTo(i - 1, state);
62 state = SCE_PLM_STRING;
63 } else if (isdigit(ch)) {
64 styler.ColourTo(i - 1, state);
65 state = SCE_PLM_NUMBER;
66 } else if (isalpha(ch)) {
67 styler.ColourTo(i - 1, state);
68 state = SCE_PLM_IDENTIFIER;
69 } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
70 ch == '=' || ch == '<' || ch == '>' || ch == ':') {
71 styler.ColourTo(i - 1, state);
72 state = SCE_PLM_OPERATOR;
73 } else if (ch == '$') {
74 styler.ColourTo(i - 1, state);
75 state = SCE_PLM_CONTROL;
77 } else if (state == SCE_PLM_COMMENT) {
78 if (ch == '*' && chNext == '/') {
79 i++;
80 styler.ColourTo(i, state);
81 state = SCE_PLM_DEFAULT;
83 } else if (state == SCE_PLM_STRING) {
84 if (ch == '\'') {
85 if (chNext == '\'') {
86 i++;
87 } else {
88 styler.ColourTo(i, state);
89 state = SCE_PLM_DEFAULT;
92 } else if (state == SCE_PLM_NUMBER) {
93 if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
94 i--;
95 styler.ColourTo(i, state);
96 state = SCE_PLM_DEFAULT;
98 } else if (state == SCE_PLM_IDENTIFIER) {
99 if (!isdigit(ch) && !isalpha(ch) && ch != '$') {
100 // Get the entire identifier.
101 char word[1024];
102 int segmentStart = styler.GetStartSegment();
103 GetRange(segmentStart, i - 1, styler, word, sizeof(word));
105 i--;
106 if (keywordlists[0]->InList(word))
107 styler.ColourTo(i, SCE_PLM_KEYWORD);
108 else
109 styler.ColourTo(i, state);
110 state = SCE_PLM_DEFAULT;
112 } else if (state == SCE_PLM_OPERATOR) {
113 if (ch != '=' && ch != '>') {
114 i--;
115 styler.ColourTo(i, state);
116 state = SCE_PLM_DEFAULT;
118 } else if (state == SCE_PLM_CONTROL) {
119 if (ch == '\r' || ch == '\n') {
120 styler.ColourTo(i - 1, state);
121 state = SCE_PLM_DEFAULT;
125 styler.ColourTo(endPos - 1, state);
128 static void FoldPlmDoc(unsigned int startPos,
129 int length,
130 int initStyle,
131 WordList *[],
132 Accessor &styler)
134 bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
135 bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
136 unsigned int endPos = startPos + length;
137 int visibleChars = 0;
138 int lineCurrent = styler.GetLine(startPos);
139 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
140 int levelCurrent = levelPrev;
141 char chNext = styler[startPos];
142 int styleNext = styler.StyleAt(startPos);
143 int style = initStyle;
144 int startKeyword = 0;
146 for (unsigned int i = startPos; i < endPos; i++) {
147 char ch = chNext;
148 chNext = styler.SafeGetCharAt(i + 1);
149 int stylePrev = style;
150 style = styleNext;
151 styleNext = styler.StyleAt(i + 1);
152 bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
154 if (stylePrev != SCE_PLM_KEYWORD && style == SCE_PLM_KEYWORD)
155 startKeyword = i;
157 if (style == SCE_PLM_KEYWORD && styleNext != SCE_PLM_KEYWORD) {
158 char word[1024];
159 GetRange(startKeyword, i, styler, word, sizeof(word));
161 if (strcmp(word, "procedure") == 0 || strcmp(word, "do") == 0)
162 levelCurrent++;
163 else if (strcmp(word, "end") == 0)
164 levelCurrent--;
167 if (foldComment) {
168 if (stylePrev != SCE_PLM_COMMENT && style == SCE_PLM_COMMENT)
169 levelCurrent++;
170 else if (stylePrev == SCE_PLM_COMMENT && style != SCE_PLM_COMMENT)
171 levelCurrent--;
174 if (atEOL) {
175 int lev = levelPrev;
176 if (visibleChars == 0 && foldCompact)
177 lev |= SC_FOLDLEVELWHITEFLAG;
178 if ((levelCurrent > levelPrev) && (visibleChars > 0))
179 lev |= SC_FOLDLEVELHEADERFLAG;
180 if (lev != styler.LevelAt(lineCurrent)) {
181 styler.SetLevel(lineCurrent, lev);
183 lineCurrent++;
184 levelPrev = levelCurrent;
185 visibleChars = 0;
188 if (!isspacechar(ch))
189 visibleChars++;
192 int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
193 styler.SetLevel(lineCurrent, levelPrev | flagsNext);
196 static const char *const plmWordListDesc[] = {
197 "Keywords",
201 LexerModule lmPLM(SCLEX_PLM, ColourisePlmDoc, "PL/M", FoldPlmDoc, plmWordListDesc);