notepad-plus-plus/lexilla/lexers/LexDMIS.cxx

368 lines
8.6 KiB
C++
Raw Normal View History

// Scintilla source code edit control
/** @file LexDMIS.cxx
** Lexer for DMIS.
**/
// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org>
// Copyright 2013-2014 by Andreas Tscharner <andy@vis.ethz.ch>
// The License.txt file describes the conditions under which this software may be distributed.
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <cctype>
#include <string>
#include <string_view>
#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
#include "WordList.h"
#include "LexAccessor.h"
#include "StyleContext.h"
#include "CharacterSet.h"
#include "LexerModule.h"
2019-05-04 18:14:48 +00:00
#include "DefaultLexer.h"
using namespace Lexilla;
static const char *const DMISWordListDesc[] = {
"DMIS Major Words",
"DMIS Minor Words",
"Unsupported DMIS Major Words",
"Unsupported DMIS Minor Words",
"Keywords for code folding start",
"Corresponding keywords for code folding end",
0
};
2019-05-04 18:14:48 +00:00
class LexerDMIS : public DefaultLexer
{
private:
char *m_wordListSets;
WordList m_majorWords;
WordList m_minorWords;
WordList m_unsupportedMajor;
WordList m_unsupportedMinor;
WordList m_codeFoldingStart;
WordList m_codeFoldingEnd;
char * SCI_METHOD UpperCase(char *item);
void SCI_METHOD InitWordListSets(void);
public:
LexerDMIS(void);
virtual ~LexerDMIS(void);
2019-05-04 18:14:48 +00:00
int SCI_METHOD Version() const override {
return Scintilla::lvRelease5;
}
2019-05-04 18:14:48 +00:00
void SCI_METHOD Release() override {
delete this;
}
2019-05-04 18:14:48 +00:00
const char * SCI_METHOD PropertyNames() override {
return NULL;
}
2019-05-04 18:14:48 +00:00
int SCI_METHOD PropertyType(const char *) override {
return -1;
}
2019-05-04 18:14:48 +00:00
const char * SCI_METHOD DescribeProperty(const char *) override {
return NULL;
}
2019-05-04 18:14:48 +00:00
Sci_Position SCI_METHOD PropertySet(const char *, const char *) override {
return -1;
}
const char * SCI_METHOD PropertyGet(const char *) override {
return NULL;
}
2019-05-04 18:14:48 +00:00
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
2019-05-04 18:14:48 +00:00
void * SCI_METHOD PrivateCall(int, void *) override {
return NULL;
}
static ILexer5 *LexerFactoryDMIS() {
return new LexerDMIS;
}
2019-05-04 18:14:48 +00:00
const char * SCI_METHOD DescribeWordListSets() override;
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess) override;
};
char * SCI_METHOD LexerDMIS::UpperCase(char *item)
{
char *itemStart;
itemStart = item;
while (item && *item) {
*item = toupper(*item);
item++;
};
return itemStart;
}
void SCI_METHOD LexerDMIS::InitWordListSets(void)
{
size_t totalLen = 0;
for (int i=0; DMISWordListDesc[i]; i++) {
totalLen += strlen(DMISWordListDesc[i]);
totalLen++;
};
totalLen++;
this->m_wordListSets = new char[totalLen];
memset(this->m_wordListSets, 0, totalLen);
for (int i=0; DMISWordListDesc[i]; i++) {
strcat(this->m_wordListSets, DMISWordListDesc[i]);
strcat(this->m_wordListSets, "\n");
};
}
LexerDMIS::LexerDMIS(void) : DefaultLexer("DMIS", SCLEX_DMIS) {
this->InitWordListSets();
this->m_majorWords.Clear();
this->m_minorWords.Clear();
this->m_unsupportedMajor.Clear();
this->m_unsupportedMinor.Clear();
this->m_codeFoldingStart.Clear();
this->m_codeFoldingEnd.Clear();
}
LexerDMIS::~LexerDMIS(void) {
delete[] this->m_wordListSets;
}
2019-05-04 18:14:48 +00:00
Sci_Position SCI_METHOD LexerDMIS::WordListSet(int n, const char *wl)
{
switch (n) {
case 0:
this->m_majorWords.Clear();
this->m_majorWords.Set(wl);
break;
case 1:
this->m_minorWords.Clear();
this->m_minorWords.Set(wl);
break;
case 2:
this->m_unsupportedMajor.Clear();
this->m_unsupportedMajor.Set(wl);
break;
case 3:
this->m_unsupportedMinor.Clear();
this->m_unsupportedMinor.Set(wl);
break;
case 4:
this->m_codeFoldingStart.Clear();
this->m_codeFoldingStart.Set(wl);
break;
case 5:
this->m_codeFoldingEnd.Clear();
this->m_codeFoldingEnd.Set(wl);
break;
default:
return -1;
break;
}
return 0;
}
const char * SCI_METHOD LexerDMIS::DescribeWordListSets()
{
return this->m_wordListSets;
}
void SCI_METHOD LexerDMIS::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, Scintilla::IDocument *pAccess)
{
2019-05-04 18:14:48 +00:00
const Sci_PositionU MAX_STR_LEN = 100;
LexAccessor styler(pAccess);
StyleContext scCTX(startPos, lengthDoc, initStyle, styler);
CharacterSet setDMISNumber(CharacterSet::setDigits, ".-+eE");
CharacterSet setDMISWordStart(CharacterSet::setAlpha, "-234", 0x80, true);
CharacterSet setDMISWord(CharacterSet::setAlpha);
bool isIFLine = false;
for (; scCTX.More(); scCTX.Forward()) {
if (scCTX.atLineEnd) {
isIFLine = false;
};
switch (scCTX.state) {
case SCE_DMIS_DEFAULT:
if (scCTX.Match('$', '$')) {
scCTX.SetState(SCE_DMIS_COMMENT);
scCTX.Forward();
};
if (scCTX.Match('\'')) {
scCTX.SetState(SCE_DMIS_STRING);
};
if (IsADigit(scCTX.ch) || ((scCTX.Match('-') || scCTX.Match('+')) && IsADigit(scCTX.chNext))) {
scCTX.SetState(SCE_DMIS_NUMBER);
break;
};
if (setDMISWordStart.Contains(scCTX.ch)) {
scCTX.SetState(SCE_DMIS_KEYWORD);
};
if (scCTX.Match('(') && (!isIFLine)) {
scCTX.SetState(SCE_DMIS_LABEL);
};
break;
case SCE_DMIS_COMMENT:
if (scCTX.atLineEnd) {
scCTX.SetState(SCE_DMIS_DEFAULT);
};
break;
case SCE_DMIS_STRING:
if (scCTX.Match('\'')) {
scCTX.SetState(SCE_DMIS_DEFAULT);
};
break;
case SCE_DMIS_NUMBER:
if (!setDMISNumber.Contains(scCTX.ch)) {
scCTX.SetState(SCE_DMIS_DEFAULT);
};
break;
case SCE_DMIS_KEYWORD:
if (!setDMISWord.Contains(scCTX.ch)) {
char tmpStr[MAX_STR_LEN];
memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
scCTX.GetCurrent(tmpStr, (MAX_STR_LEN-1));
Update to Scintilla 5.3.2 and Lexilla 5.2.1 update to https://www.scintilla.org/scintilla532.zip with: Released 6 December 2022. Add SCI_REPLACETARGETMINIMAL to change text without causing unchanged prefix and suffix to be marked as modified in change history. Draw background colour for EOL annotations with standard and boxed visuals. Add SCI_GETSTYLEDTEXTFULL to support 64-bit document positions on Win32 replacing SCI_GETSTYLEDTEXT which is not safe for huge documents. Feature #1455. Send SCN_AUTOCCOMPLETED for SCI_AUTOCSHOW triggering insertion because of SCI_AUTOCSETCHOOSESINGLE mode. Feature #1459. Change 'paragraph up' commands SCI_PARAUP and SCI_PARAUPEXTEND to go to the start position of the paragraph containing the caret. Only if the caret is already at the start of the paragraph will it go to the start of the previous paragraph. Bug #2363. Change release compilation optimization option to favour speed over space. -O2 for MSVC and -O3 for gcc and clang. On Win32, avoid blurry display with DirectWrite in GDI scaling mode. Bug #2344. On Win32, use the top-level window to find the monitor for DirectWrite rendering parameters. Temporarily switch DPI awareness to find correct monitor in GDI scaling mode. Bug #2344. On Qt, implement SCI_SETRECTANGULARSELECTIONMODIFIER for all platforms. On Qt, allow string form XPM images for SCI_REGISTERIMAGE. and https://www.scintilla.org/lexilla521.zip with Released 6 December 2022. Update to Unicode 14. Feature #1461. Change default compilation optimization option to favour speed over space. -O2 for MSVC and -O3 for gcc and clang. Batch: Fix comments starting inside strings. Issue #115. F#: Lex signed numeric literals more accurately. Issue #110, Issue #111. F#: Add specifiers for 64-bit integer and floating point literals. Issue #112. Markdown: Stop styling numbers at line start in PRECHAR style. Issue #117. PowerShell: Recognise numeric literals more accurately. Issue #118. Close #12624
2022-12-10 12:35:16 +00:00
// The following strncpy is copying from a string back onto itself which is weird and causes warnings
// but is harmless so turn off the warning
Update to Scintilla 5.3.3 and Lexilla 5.2.2 update to https://www.scintilla.org/scintilla533.zip with: 1. Released 8 February 2023. 2. Fix SCI_LINESJOIN bug where carriage returns were incorrectly retained. Bug #2372. 3. Fix SCI_VERTICALCENTRECARET to update the vertical scroll position. 4. When an autocompletion list is shown in response to SCN_CHARADDED, do not process character as fill-up or stop. This avoids closing immediately when a character may both trigger and finish autocompletion. 5. On Cocoa fix character input bug where dotless 'i' and some other extended Latin characters could not be entered. The change also stops SCI_ASSIGNCMDKEY from working with these characters on Cocoa. Bug #2374. 6. On GTK, support IME context. Feature #1476. 7. On GTK on Win32, fix scrolling speed to not be too fast. Bug #2375. 8. On Qt, fix indicator drawing past left of text pane over margin. Bug #2373, Bug #1956. 9. On Qt, allow scrolling with mouse wheel when scroll bar hidden. and https://www.scintilla.org/lexilla522.zip with 1. Released 8 February 2023. 2. C++: Fix keywords that start with non-ASCII. Also affects other lexers. Issue #130. 3. Matlab: Include more prefix and suffix characters in numeric literals. Issue #120. 4. Matlab: More accurate treatment of line ends inside strings. Matlab and Octave are different here. Issue #18. 5. Modula-3: Don't treat identifier suffix that matches keyword as keyword. Issue #129. 6. Modula-3: Fix endless loop in folder. Issue #128. 7. Modula-3: Fix access to lines beyond document end in folder. Issue #131. 8. Python: Don't highlight match and case as keywords in contexts where they probably aren't used as keywords. Pull request #122. 9. X12: Support empty envelopes. Bug #2369. update CMakeLists.txt to latest changes within vcxproj file Close #13082
2023-02-09 16:57:24 +00:00
#if defined(__GNUC__) && !defined(__clang__)
Update to Scintilla 5.3.2 and Lexilla 5.2.1 update to https://www.scintilla.org/scintilla532.zip with: Released 6 December 2022. Add SCI_REPLACETARGETMINIMAL to change text without causing unchanged prefix and suffix to be marked as modified in change history. Draw background colour for EOL annotations with standard and boxed visuals. Add SCI_GETSTYLEDTEXTFULL to support 64-bit document positions on Win32 replacing SCI_GETSTYLEDTEXT which is not safe for huge documents. Feature #1455. Send SCN_AUTOCCOMPLETED for SCI_AUTOCSHOW triggering insertion because of SCI_AUTOCSETCHOOSESINGLE mode. Feature #1459. Change 'paragraph up' commands SCI_PARAUP and SCI_PARAUPEXTEND to go to the start position of the paragraph containing the caret. Only if the caret is already at the start of the paragraph will it go to the start of the previous paragraph. Bug #2363. Change release compilation optimization option to favour speed over space. -O2 for MSVC and -O3 for gcc and clang. On Win32, avoid blurry display with DirectWrite in GDI scaling mode. Bug #2344. On Win32, use the top-level window to find the monitor for DirectWrite rendering parameters. Temporarily switch DPI awareness to find correct monitor in GDI scaling mode. Bug #2344. On Qt, implement SCI_SETRECTANGULARSELECTIONMODIFIER for all platforms. On Qt, allow string form XPM images for SCI_REGISTERIMAGE. and https://www.scintilla.org/lexilla521.zip with Released 6 December 2022. Update to Unicode 14. Feature #1461. Change default compilation optimization option to favour speed over space. -O2 for MSVC and -O3 for gcc and clang. Batch: Fix comments starting inside strings. Issue #115. F#: Lex signed numeric literals more accurately. Issue #110, Issue #111. F#: Add specifiers for 64-bit integer and floating point literals. Issue #112. Markdown: Stop styling numbers at line start in PRECHAR style. Issue #117. PowerShell: Recognise numeric literals more accurately. Issue #118. Close #12624
2022-12-10 12:35:16 +00:00
// Disable warning for strncpy
#pragma GCC diagnostic ignored "-Wrestrict"
#endif
strncpy(tmpStr, this->UpperCase(tmpStr), (MAX_STR_LEN-1));
if (this->m_minorWords.InList(tmpStr)) {
scCTX.ChangeState(SCE_DMIS_MINORWORD);
};
if (this->m_majorWords.InList(tmpStr)) {
isIFLine = (strcmp(tmpStr, "IF") == 0);
scCTX.ChangeState(SCE_DMIS_MAJORWORD);
};
if (this->m_unsupportedMajor.InList(tmpStr)) {
scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MAJOR);
};
if (this->m_unsupportedMinor.InList(tmpStr)) {
scCTX.ChangeState(SCE_DMIS_UNSUPPORTED_MINOR);
};
if (scCTX.Match('(') && (!isIFLine)) {
scCTX.SetState(SCE_DMIS_LABEL);
} else {
scCTX.SetState(SCE_DMIS_DEFAULT);
};
};
break;
case SCE_DMIS_LABEL:
if (scCTX.Match(')')) {
scCTX.SetState(SCE_DMIS_DEFAULT);
};
break;
};
};
scCTX.Complete();
}
void SCI_METHOD LexerDMIS::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, Scintilla::IDocument *pAccess)
{
const int MAX_STR_LEN = 100;
LexAccessor styler(pAccess);
2019-05-04 18:14:48 +00:00
Sci_PositionU endPos = startPos + lengthDoc;
char chNext = styler[startPos];
2019-05-04 18:14:48 +00:00
Sci_Position lineCurrent = styler.GetLine(startPos);
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
int strPos = 0;
bool foldWordPossible = false;
CharacterSet setDMISFoldWord(CharacterSet::setAlpha);
char *tmpStr;
tmpStr = new char[MAX_STR_LEN];
memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
2019-05-04 18:14:48 +00:00
for (Sci_PositionU i=startPos; i<endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i+1);
bool atEOL = ((ch == '\r' && chNext != '\n') || (ch == '\n'));
if (strPos >= (MAX_STR_LEN-1)) {
strPos = MAX_STR_LEN-1;
};
int style = styler.StyleAt(i);
bool noFoldPos = ((style == SCE_DMIS_COMMENT) || (style == SCE_DMIS_STRING));
if (foldWordPossible) {
if (setDMISFoldWord.Contains(ch)) {
tmpStr[strPos++] = ch;
} else {
tmpStr = this->UpperCase(tmpStr);
if (this->m_codeFoldingStart.InList(tmpStr) && (!noFoldPos)) {
levelCurrent++;
};
if (this->m_codeFoldingEnd.InList(tmpStr) && (!noFoldPos)) {
levelCurrent--;
};
memset(tmpStr, 0, MAX_STR_LEN*sizeof(char));
strPos = 0;
foldWordPossible = false;
};
} else {
if (setDMISFoldWord.Contains(ch)) {
tmpStr[strPos++] = ch;
foldWordPossible = true;
};
};
if (atEOL || (i == (endPos-1))) {
int lev = levelPrev;
if (levelCurrent > levelPrev) {
lev |= SC_FOLDLEVELHEADERFLAG;
};
if (lev != styler.LevelAt(lineCurrent)) {
styler.SetLevel(lineCurrent, lev);
};
lineCurrent++;
levelPrev = levelCurrent;
};
};
delete[] tmpStr;
}
LexerModule lmDMIS(SCLEX_DMIS, LexerDMIS::LexerFactoryDMIS, "DMIS", DMISWordListDesc);