Refactor: CString optimizations
[TortoiseGit.git] / ext / scintilla / lexers / LexDMIS.cxx
blob77e2cffcc0eb001ba92896c7ddea9d12fddc0d3a
1 // Scintilla source code edit control
2 /** @file LexDMIS.cxx
3 ** Lexer for DMIS.
4 **/
5 // Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
6 // Copyright 2013-2014 by Andreas Tscharner <andy@vis.ethz.ch>
7 // The License.txt file describes the conditions under which this software may be distributed.
10 #include <cstdlib>
11 #include <cassert>
12 #include <cstring>
13 #include <cctype>
15 #include "ILexer.h"
16 #include "Scintilla.h"
17 #include "SciLexer.h"
19 #include "WordList.h"
20 #include "LexAccessor.h"
21 #include "StyleContext.h"
22 #include "CharacterSet.h"
23 #include "LexerModule.h"
25 #ifdef SCI_NAMESPACE
26 using namespace Scintilla;
27 #endif
30 static const char *const DMISWordListDesc[] = {
31 "DMIS Major Words",
32 "DMIS Minor Words",
33 "Unsupported DMIS Major Words",
34 "Unsupported DMIS Minor Words",
35 "Keywords for code folding start",
36 "Corresponding keywords for code folding end",
41 class LexerDMIS : public ILexer
43 private:
44 char *m_wordListSets;
45 WordList m_majorWords;
46 WordList m_minorWords;
47 WordList m_unsupportedMajor;
48 WordList m_unsupportedMinor;
49 WordList m_codeFoldingStart;
50 WordList m_codeFoldingEnd;
52 char * SCI_METHOD UpperCase(char *item);
53 void SCI_METHOD InitWordListSets(void);
55 public:
56 LexerDMIS(void);
57 virtual ~LexerDMIS(void);
59 int SCI_METHOD Version() const {
60 return lvOriginal;
63 void SCI_METHOD Release() {
64 delete this;
67 const char * SCI_METHOD PropertyNames() {
68 return NULL;
71 int SCI_METHOD PropertyType(const char *) {
72 return -1;
75 const char * SCI_METHOD DescribeProperty(const char *) {
76 return NULL;
79 int SCI_METHOD PropertySet(const char *, const char *) {
80 return -1;
83 int SCI_METHOD WordListSet(int n, const char *wl);
85 void * SCI_METHOD PrivateCall(int, void *) {
86 return NULL;
89 static ILexer *LexerFactoryDMIS() {
90 return new LexerDMIS;
93 const char * SCI_METHOD DescribeWordListSets();
94 void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
95 void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
99 char * SCI_METHOD LexerDMIS::UpperCase(char *item)
101 char *itemStart;
104 itemStart = item;
105 while (item && *item) {
106 *item = toupper(*item);
107 item++;
109 return itemStart;
112 void SCI_METHOD LexerDMIS::InitWordListSets(void)
114 size_t totalLen = 0;
117 for (int i=0; DMISWordListDesc[i]; i++) {
118 totalLen += strlen(DMISWordListDesc[i]);
119 totalLen++;
122 totalLen++;
123 this->m_wordListSets = new char[totalLen];
124 memset(this->m_wordListSets, 0, totalLen);
126 for (int i=0; DMISWordListDesc[i]; i++) {
127 strcat(this->m_wordListSets, DMISWordListDesc[i]);
128 strcat(this->m_wordListSets, "\n");
133 LexerDMIS::LexerDMIS(void) {
134 this->InitWordListSets();
136 this->m_majorWords.Clear();
137 this->m_minorWords.Clear();
138 this->m_unsupportedMajor.Clear();
139 this->m_unsupportedMinor.Clear();
140 this->m_codeFoldingStart.Clear();
141 this->m_codeFoldingEnd.Clear();
144 LexerDMIS::~LexerDMIS(void) {
145 delete[] this->m_wordListSets;
148 int SCI_METHOD LexerDMIS::WordListSet(int n, const char *wl)
150 switch (n) {
151 case 0:
152 this->m_majorWords.Clear();
153 this->m_majorWords.Set(wl);
154 break;
155 case 1:
156 this->m_minorWords.Clear();
157 this->m_minorWords.Set(wl);
158 break;
159 case 2:
160 this->m_unsupportedMajor.Clear();
161 this->m_unsupportedMajor.Set(wl);
162 break;
163 case 3:
164 this->m_unsupportedMinor.Clear();
165 this->m_unsupportedMinor.Set(wl);
166 break;
167 case 4:
168 this->m_codeFoldingStart.Clear();
169 this->m_codeFoldingStart.Set(wl);
170 break;
171 case 5:
172 this->m_codeFoldingEnd.Clear();
173 this->m_codeFoldingEnd.Set(wl);
174 break;
175 default:
176 return -1;
177 break;
180 return 0;
183 const char * SCI_METHOD LexerDMIS::DescribeWordListSets()
185 return this->m_wordListSets;
188 void SCI_METHOD LexerDMIS::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess)
190 const unsigned int MAX_STR_LEN = 100;
192 LexAccessor styler(pAccess);
193 StyleContext scCTX(startPos, lengthDoc, initStyle, styler);
194 CharacterSet setDMISNumber(CharacterSet::setDigits, ".-+eE");
195 CharacterSet setDMISWordStart(CharacterSet::setAlpha, "-234", 0x80, true);
196 CharacterSet setDMISWord(CharacterSet::setAlpha);
199 bool isIFLine = false;
201 for (; scCTX.More(); scCTX.Forward()) {
202 if (scCTX.atLineEnd) {
203 isIFLine = false;
206 switch (scCTX.state) {
207 case SCE_DMIS_DEFAULT:
208 if (scCTX.Match('$', '$')) {
209 scCTX.SetState(SCE_DMIS_COMMENT);
210 scCTX.Forward();
212 if (scCTX.Match('\'')) {
213 scCTX.SetState(SCE_DMIS_STRING);
215 if (IsADigit(scCTX.ch) || ((scCTX.Match('-') || scCTX.Match('+')) && IsADigit(scCTX.chNext))) {
216 scCTX.SetState(SCE_DMIS_NUMBER);
217 break;
219 if (setDMISWordStart.Contains(scCTX.ch)) {
220 scCTX.SetState(SCE_DMIS_KEYWORD);
222 if (scCTX.Match('(') && (!isIFLine)) {
223 scCTX.SetState(SCE_DMIS_LABEL);
225 break;
227 case SCE_DMIS_COMMENT:
228 if (scCTX.atLineEnd) {
229 scCTX.SetState(SCE_DMIS_DEFAULT);
231 break;
233 case SCE_DMIS_STRING:
234 if (scCTX.Match('\'')) {
235 scCTX.SetState(SCE_DMIS_DEFAULT);
237 break;
239 case SCE_DMIS_NUMBER:
240 if (!setDMISNumber.Contains(scCTX.ch)) {
241 scCTX.SetState(SCE_DMIS_DEFAULT);
243 break;
245 case SCE_DMIS_KEYWORD:
246 if (!setDMISWord.Contains(scCTX.ch)) {
247 char tmpStr[MAX_STR_LEN];
248 memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
249 scCTX.GetCurrent(tmpStr, (MAX_STR_LEN-1));
250 strncpy(tmpStr, this->UpperCase(tmpStr), (MAX_STR_LEN-1));
252 if (this->m_minorWords.InList(tmpStr)) {
253 scCTX.ChangeState(SCE_DMIS_MINORWORD);
255 if (this->m_majorWords.InList(tmpStr)) {
256 isIFLine = (strcmp(tmpStr, "IF") == 0);
257 scCTX.ChangeState(SCE_DMIS_MAJORWORD);
259 if (this->m_unsupportedMajor.InList(tmpStr)) {
260 scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MAJOR);
262 if (this->m_unsupportedMinor.InList(tmpStr)) {
263 scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MINOR);
266 if (scCTX.Match('(') && (!isIFLine)) {
267 scCTX.SetState(SCE_DMIS_LABEL);
268 } else {
269 scCTX.SetState(SCE_DMIS_DEFAULT);
272 break;
274 case SCE_DMIS_LABEL:
275 if (scCTX.Match(')')) {
276 scCTX.SetState(SCE_DMIS_DEFAULT);
278 break;
281 scCTX.Complete();
284 void SCI_METHOD LexerDMIS::Fold(unsigned int startPos, int lengthDoc, int, IDocument *pAccess)
286 const int MAX_STR_LEN = 100;
288 LexAccessor styler(pAccess);
289 unsigned int endPos = startPos + lengthDoc;
290 char chNext = styler[startPos];
291 int lineCurrent = styler.GetLine(startPos);
292 int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
293 int levelCurrent = levelPrev;
294 int strPos = 0;
295 bool foldWordPossible = false;
296 CharacterSet setDMISFoldWord(CharacterSet::setAlpha);
297 char *tmpStr;
300 tmpStr = new char[MAX_STR_LEN];
301 memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
303 for (unsigned int i=startPos; i<endPos; i++) {
304 char ch = chNext;
305 chNext = styler.SafeGetCharAt(i+1);
307 bool atEOL = ((ch == '\r' && chNext != '\n') || (ch == '\n'));
309 if (strPos >= (MAX_STR_LEN-1)) {
310 strPos = MAX_STR_LEN-1;
313 int style = styler.StyleAt(i);
314 bool noFoldPos = ((style == SCE_DMIS_COMMENT) || (style == SCE_DMIS_STRING));
316 if (foldWordPossible) {
317 if (setDMISFoldWord.Contains(ch)) {
318 tmpStr[strPos++] = ch;
319 } else {
320 tmpStr = this->UpperCase(tmpStr);
321 if (this->m_codeFoldingStart.InList(tmpStr) && (!noFoldPos)) {
322 levelCurrent++;
324 if (this->m_codeFoldingEnd.InList(tmpStr) && (!noFoldPos)) {
325 levelCurrent--;
327 memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
328 strPos = 0;
329 foldWordPossible = false;
331 } else {
332 if (setDMISFoldWord.Contains(ch)) {
333 tmpStr[strPos++] = ch;
334 foldWordPossible = true;
338 if (atEOL || (i == (endPos-1))) {
339 int lev = levelPrev;
341 if (levelCurrent > levelPrev) {
342 lev |= SC_FOLDLEVELHEADERFLAG;
344 if (lev != styler.LevelAt(lineCurrent)) {
345 styler.SetLevel(lineCurrent, lev);
347 lineCurrent++;
348 levelPrev = levelCurrent;
351 delete[] tmpStr;
355 LexerModule lmDMIS(SCLEX_DMIS, LexerDMIS::LexerFactoryDMIS, "DMIS", DMISWordListDesc);