diff options
Diffstat (limited to 'lexers/LexPowerPro.cxx')
-rw-r--r-- | lexers/LexPowerPro.cxx | 628 |
1 files changed, 0 insertions, 628 deletions
diff --git a/lexers/LexPowerPro.cxx b/lexers/LexPowerPro.cxx deleted file mode 100644 index 34debff24..000000000 --- a/lexers/LexPowerPro.cxx +++ /dev/null @@ -1,628 +0,0 @@ -// Scintilla source code edit control -// @file LexPowerPro.cxx -// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com -// PowerPro lexer is written by Christopher Bean (cbean@cb-software.net) -// -// Lexer code heavily borrowed from: -// LexAU3.cxx by Jos van der Zande -// LexCPP.cxx by Neil Hodgson -// LexVB.cxx by Neil Hodgson -// -// Changes: -// 2008-10-25 - Initial release -// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that -// local isFunction = "" and local functions = "" don't get falsely highlighted -// 2008-12-14 - Added bounds checking for szFirstWord and szDo -// - Replaced SetOfCharacters with CharacterSet -// - Made sure that CharacterSet::Contains is passed only positive values -// - Made sure that the return value of Accessor::SafeGetCharAt is positive before -// passing to functions that require positive values like isspacechar() -// - Removed unused visibleChars processing from ColourisePowerProDoc() -// - Fixed bug with folding logic where line continuations didn't end where -// they were supposed to -// - Moved all helper functions to the top of the file -// 2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented -// - Modified HasFunction function to be a bit more robust -// - Renamed HasFunction function to IsFunction -// - Cleanup -// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> -// The License.txt file describes the conditions under which this software may be distributed. - -#include <string.h> -#include <assert.h> -#include <ctype.h> - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "WordList.h" -#include "LexAccessor.h" -#include "Accessor.h" -#include "StyleContext.h" -#include "CharacterSet.h" -#include "LexerModule.h" - -using namespace Scintilla; - -static inline bool IsStreamCommentStyle(int style) { - return style == SCE_POWERPRO_COMMENTBLOCK; -} - -static inline bool IsLineEndChar(unsigned char ch) { - return ch == 0x0a //LF - || ch == 0x0c //FF - || ch == 0x0d; //CR -} - -static bool IsContinuationLine(Sci_PositionU szLine, Accessor &styler) -{ - Sci_Position startPos = styler.LineStart(szLine); - Sci_Position endPos = styler.LineStart(szLine + 1) - 2; - while (startPos < endPos) - { - char stylech = styler.StyleAt(startPos); - if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) { - char ch = styler.SafeGetCharAt(endPos); - char chPrev = styler.SafeGetCharAt(endPos - 1); - char chPrevPrev = styler.SafeGetCharAt(endPos - 2); - if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) - return (chPrevPrev == ';' && chPrev == ';' && ch == '+'); - } - endPos--; // skip to next char - } - return false; -} - -// Routine to find first none space on the current line and return its Style -// needed for comment lines not starting on pos 1 -static int GetStyleFirstWord(Sci_Position szLine, Accessor &styler) -{ - Sci_Position startPos = styler.LineStart(szLine); - Sci_Position endPos = styler.LineStart(szLine + 1) - 1; - char ch = styler.SafeGetCharAt(startPos); - - while (ch > 0 && isspacechar(ch) && startPos < endPos) - { - startPos++; // skip to next char - ch = styler.SafeGetCharAt(startPos); - } - return styler.StyleAt(startPos); -} - -//returns true if there is a function to highlight -//used to highlight <name> in 'function <name>' -//note: -// sample line (without quotes): "\tfunction asdf() -// currentPos will be the position of 'a' -static bool IsFunction(Accessor &styler, Sci_PositionU currentPos) { - - const char function[10] = "function "; //10 includes \0 - unsigned int numberOfCharacters = sizeof(function) - 1; - Sci_PositionU position = currentPos - numberOfCharacters; - - //compare each character with the letters in the function array - //return false if ALL don't match - for (Sci_PositionU i = 0; i < numberOfCharacters; i++) { - char c = styler.SafeGetCharAt(position++); - if (c != function[i]) - return false; - } - - //make sure that there are only spaces (or tabs) between the beginning - //of the line and the function declaration - position = currentPos - numberOfCharacters - 1; //-1 to move to char before 'function' - for (Sci_PositionU j = 0; j < 16; j++) { //check up to 16 preceeding characters - char c = styler.SafeGetCharAt(position--, '\0'); //if can't read char, return NUL (past beginning of document) - if (c <= 0) //reached beginning of document - return true; - if (c > 0 && IsLineEndChar(c)) - return true; - else if (c > 0 && !IsASpaceOrTab(c)) - return false; - } - - //fall-through - return false; -} - -static void ColourisePowerProDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], - Accessor &styler, bool caseSensitive) { - - WordList &keywords = *keywordlists[0]; - WordList &keywords2 = *keywordlists[1]; - WordList &keywords3 = *keywordlists[2]; - WordList &keywords4 = *keywordlists[3]; - - //define the character sets - CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); - CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); - - StyleContext sc(startPos, length, initStyle, styler); - char s_save[100]; //for last line highlighting - - //are there only spaces between the first letter of the line and the beginning of the line - bool onlySpaces = true; - - for (; sc.More(); sc.Forward()) { - - // save the total current word for eof processing - char s[100]; - sc.GetCurrentLowered(s, sizeof(s)); - - if ((sc.ch > 0) && setWord.Contains(sc.ch)) - { - strcpy(s_save,s); - int tp = static_cast<int>(strlen(s_save)); - if (tp < 99) { - s_save[tp] = static_cast<char>(tolower(sc.ch)); - s_save[tp+1] = '\0'; - } - } - - if (sc.atLineStart) { - if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) { - // Prevent SCE_POWERPRO_STRINGEOL from leaking back to previous line which - // ends with a line continuation by locking in the state upto this position. - sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING); - } - } - - // Determine if the current state should terminate. - switch (sc.state) { - case SCE_POWERPRO_OPERATOR: - sc.SetState(SCE_POWERPRO_DEFAULT); - break; - - case SCE_POWERPRO_NUMBER: - - if (!IsADigit(sc.ch)) - sc.SetState(SCE_POWERPRO_DEFAULT); - - break; - - case SCE_POWERPRO_IDENTIFIER: - //if ((sc.ch > 0) && !setWord.Contains(sc.ch) || (sc.ch == '.')) { // use this line if don't want to match keywords with . in them. ie: win.debug will match both win and debug so win debug will also be colorized - if ((sc.ch > 0) && !setWord.Contains(sc.ch)){ // || (sc.ch == '.')) { // use this line if you want to match keywords with a . ie: win.debug will only match win.debug neither win nor debug will be colorized separately - char s[1000]; - if (caseSensitive) { - sc.GetCurrent(s, sizeof(s)); - } else { - sc.GetCurrentLowered(s, sizeof(s)); - } - - if (keywords.InList(s)) { - sc.ChangeState(SCE_POWERPRO_WORD); - } else if (keywords2.InList(s)) { - sc.ChangeState(SCE_POWERPRO_WORD2); - } else if (keywords3.InList(s)) { - sc.ChangeState(SCE_POWERPRO_WORD3); - } else if (keywords4.InList(s)) { - sc.ChangeState(SCE_POWERPRO_WORD4); - } - sc.SetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_LINECONTINUE: - if (sc.atLineStart) { - sc.SetState(SCE_POWERPRO_DEFAULT); - } else if (sc.Match('/', '*') || sc.Match('/', '/')) { - sc.SetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_COMMENTBLOCK: - if (sc.Match('*', '/')) { - sc.Forward(); - sc.ForwardSetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_COMMENTLINE: - if (sc.atLineStart) { - sc.SetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_DOUBLEQUOTEDSTRING: - if (sc.atLineEnd) { - sc.ChangeState(SCE_POWERPRO_STRINGEOL); - } else if (sc.ch == '\\') { - if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { - sc.Forward(); - } - } else if (sc.ch == '\"') { - sc.ForwardSetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_SINGLEQUOTEDSTRING: - if (sc.atLineEnd) { - sc.ChangeState(SCE_POWERPRO_STRINGEOL); - } else if (sc.ch == '\\') { - if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') { - sc.Forward(); - } - } else if (sc.ch == '\'') { - sc.ForwardSetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_STRINGEOL: - if (sc.atLineStart) { - sc.SetState(SCE_POWERPRO_DEFAULT); - } - break; - - case SCE_POWERPRO_VERBATIM: - if (sc.ch == '\"') { - if (sc.chNext == '\"') { - sc.Forward(); - } else { - sc.ForwardSetState(SCE_POWERPRO_DEFAULT); - } - } - break; - - case SCE_POWERPRO_ALTQUOTE: - if (sc.ch == '#') { - if (sc.chNext == '#') { - sc.Forward(); - } else { - sc.ForwardSetState(SCE_POWERPRO_DEFAULT); - } - } - break; - - case SCE_POWERPRO_FUNCTION: - if (isspacechar(sc.ch) || sc.ch == '(') { - sc.SetState(SCE_POWERPRO_DEFAULT); - } - break; - } - - // Determine if a new state should be entered. - if (sc.state == SCE_POWERPRO_DEFAULT) { - if (sc.Match('?', '\"')) { - sc.SetState(SCE_POWERPRO_VERBATIM); - sc.Forward(); - } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) { - sc.SetState(SCE_POWERPRO_NUMBER); - }else if (sc.Match('?','#')) { - if (sc.ch == '?' && sc.chNext == '#') { - sc.SetState(SCE_POWERPRO_ALTQUOTE); - sc.Forward(); - } - } else if (IsFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>' - sc.SetState(SCE_POWERPRO_FUNCTION); - } else if (onlySpaces && sc.ch == '@') { //alternate function definition [label] - sc.SetState(SCE_POWERPRO_FUNCTION); - } else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) { - sc.SetState(SCE_POWERPRO_IDENTIFIER); - } else if (sc.Match(";;+")) { - sc.SetState(SCE_POWERPRO_LINECONTINUE); - } else if (sc.Match('/', '*')) { - sc.SetState(SCE_POWERPRO_COMMENTBLOCK); - sc.Forward(); // Eat the * so it isn't used for the end of the comment - } else if (sc.Match('/', '/')) { - sc.SetState(SCE_POWERPRO_COMMENTLINE); - } else if (onlySpaces && sc.ch == ';') { //legacy comment that can only have blank space in front of it - sc.SetState(SCE_POWERPRO_COMMENTLINE); - } else if (sc.Match(";;")) { - sc.SetState(SCE_POWERPRO_COMMENTLINE); - } else if (sc.ch == '\"') { - sc.SetState(SCE_POWERPRO_DOUBLEQUOTEDSTRING); - } else if (sc.ch == '\'') { - sc.SetState(SCE_POWERPRO_SINGLEQUOTEDSTRING); - } else if (isoperator(static_cast<char>(sc.ch))) { - sc.SetState(SCE_POWERPRO_OPERATOR); - } - } - - //maintain a record of whether or not all the preceding characters on - //a line are space characters - if (onlySpaces && !IsASpaceOrTab(sc.ch)) - onlySpaces = false; - - //reset when starting a new line - if (sc.atLineEnd) - onlySpaces = true; - } - - //************************************* - // Colourize the last word correctly - //************************************* - if (sc.state == SCE_POWERPRO_IDENTIFIER) - { - if (keywords.InList(s_save)) { - sc.ChangeState(SCE_POWERPRO_WORD); - sc.SetState(SCE_POWERPRO_DEFAULT); - } - else if (keywords2.InList(s_save)) { - sc.ChangeState(SCE_POWERPRO_WORD2); - sc.SetState(SCE_POWERPRO_DEFAULT); - } - else if (keywords3.InList(s_save)) { - sc.ChangeState(SCE_POWERPRO_WORD3); - sc.SetState(SCE_POWERPRO_DEFAULT); - } - else if (keywords4.InList(s_save)) { - sc.ChangeState(SCE_POWERPRO_WORD4); - sc.SetState(SCE_POWERPRO_DEFAULT); - } - else { - sc.SetState(SCE_POWERPRO_DEFAULT); - } - } - sc.Complete(); -} - -static void FoldPowerProDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler) -{ - //define the character sets - CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true); - CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true); - - //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function) - bool isFoldingAll = true; - - Sci_Position endPos = startPos + length; - Sci_Position lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly - - // get settings from the config files for folding comments and preprocessor lines - bool foldComment = styler.GetPropertyInt("fold.comment") != 0; - bool foldInComment = styler.GetPropertyInt("fold.comment") == 2; - bool foldCompact = true; - - // Backtrack to previous line in case need to fix its fold status - Sci_Position lineCurrent = styler.GetLine(startPos); - if (startPos > 0) { - isFoldingAll = false; - if (lineCurrent > 0) { - lineCurrent--; - startPos = styler.LineStart(lineCurrent); - } - } - // vars for style of previous/current/next lines - int style = GetStyleFirstWord(lineCurrent,styler); - int stylePrev = 0; - - // find the first previous line without continuation character at the end - while ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler)) - || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) { - lineCurrent--; - startPos = styler.LineStart(lineCurrent); - } - - if (lineCurrent > 0) { - stylePrev = GetStyleFirstWord(lineCurrent-1,styler); - } - - // vars for getting first word to check for keywords - bool isFirstWordStarted = false; - bool isFirstWordEnded = false; - - const unsigned int FIRST_WORD_MAX_LEN = 10; - char szFirstWord[FIRST_WORD_MAX_LEN] = ""; - unsigned int firstWordLen = 0; - - char szDo[3]=""; - int szDolen = 0; - bool isDoLastWord = false; - - // var for indentlevel - int levelCurrent = SC_FOLDLEVELBASE; - if (lineCurrent > 0) - levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; - int levelNext = levelCurrent; - - int visibleChars = 0; - int functionCount = 0; - - char chNext = styler.SafeGetCharAt(startPos); - char chPrev = '\0'; - char chPrevPrev = '\0'; - char chPrevPrevPrev = '\0'; - - for (Sci_Position i = startPos; i < endPos; i++) { - - char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); - - if ((ch > 0) && setWord.Contains(ch)) - visibleChars++; - - // get the syle for the current character neede to check in comment - int stylech = styler.StyleAt(i); - - // start the capture of the first word - if (!isFirstWordStarted && (ch > 0)) { - if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') { - isFirstWordStarted = true; - if (firstWordLen < FIRST_WORD_MAX_LEN - 1) { - szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch)); - szFirstWord[firstWordLen] = '\0'; - } - } - } // continue capture of the first word on the line - else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) { - if (!setWord.Contains(ch)) { - isFirstWordEnded = true; - } - else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) { - szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch)); - szFirstWord[firstWordLen] = '\0'; - } - } - - if (stylech != SCE_POWERPRO_COMMENTLINE) { - - //reset isDoLastWord if we find a character(ignoring spaces) after 'do' - if (isDoLastWord && (ch > 0) && setWord.Contains(ch)) - isDoLastWord = false; - - // --find out if the word "do" is the last on a "if" line-- - // collect each letter and put it into a buffer 2 chars long - // if we end up with "do" in the buffer when we reach the end of - // the line, "do" was the last word on the line - if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "if") == 0) { - if (szDolen == 2) { - szDo[0] = szDo[1]; - szDo[1] = static_cast<char>(tolower(ch)); - szDo[2] = '\0'; - - if (strcmp(szDo, "do") == 0) - isDoLastWord = true; - - } else if (szDolen < 2) { - szDo[szDolen++] = static_cast<char>(tolower(ch)); - szDo[szDolen] = '\0'; - } - } - } - - // End of Line found so process the information - if ((ch == '\r' && chNext != '\n') // \r\n - || ch == '\n' // \n - || i == endPos) { // end of selection - - // ************************** - // Folding logic for Keywords - // ************************** - - // if a keyword is found on the current line and the line doesn't end with ;;+ (continuation) - // and we are not inside a commentblock. - if (firstWordLen > 0 - && chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';' - && (!IsStreamCommentStyle(style) || foldInComment) ) { - - // only fold "if" last keyword is "then" (else its a one line if) - if (strcmp(szFirstWord, "if") == 0 && isDoLastWord) - levelNext++; - - // create new fold for these words - if (strcmp(szFirstWord, "for") == 0) - levelNext++; - - //handle folding for functions/labels - //Note: Functions and labels don't have an explicit end like [end function] - // 1. functions/labels end at the start of another function - // 2. functions/labels end at the end of the file - if ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) { - if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script) - - if (functionCount > 0) { - levelCurrent--; - } else { - levelNext++; - } - functionCount++; - - } else { //if just folding a small piece (by clicking on the minus sign next to the word) - levelCurrent--; - } - } - - // end the fold for these words before the current line - if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "endfor") == 0) { - levelNext--; - levelCurrent--; - } - - // end the fold for these words before the current line and Start new fold - if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 ) - levelCurrent--; - - } - // Preprocessor and Comment folding - int styleNext = GetStyleFirstWord(lineCurrent + 1,styler); - - // ********************************* - // Folding logic for Comment blocks - // ********************************* - if (foldComment && IsStreamCommentStyle(style)) { - - // Start of a comment block - if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) { - levelNext++; - } // fold till the last line for normal comment lines - else if (IsStreamCommentStyle(stylePrev) - && styleNext != SCE_POWERPRO_COMMENTLINE - && stylePrev == SCE_POWERPRO_COMMENTLINE - && style == SCE_POWERPRO_COMMENTLINE) { - levelNext--; - } // fold till the one but last line for Blockcomment lines - else if (IsStreamCommentStyle(stylePrev) - && styleNext != SCE_POWERPRO_COMMENTBLOCK - && style == SCE_POWERPRO_COMMENTBLOCK) { - levelNext--; - levelCurrent--; - } - } - - int levelUse = levelCurrent; - int lev = levelUse | levelNext << 16; - if (visibleChars == 0 && foldCompact) - lev |= SC_FOLDLEVELWHITEFLAG; - if (levelUse < levelNext) - lev |= SC_FOLDLEVELHEADERFLAG; - if (lev != styler.LevelAt(lineCurrent)) - styler.SetLevel(lineCurrent, lev); - - // reset values for the next line - lineCurrent++; - stylePrev = style; - style = styleNext; - levelCurrent = levelNext; - visibleChars = 0; - - // if the last characters are ;;+ then don't reset since the line continues on the next line. - if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') { - firstWordLen = 0; - szDolen = 0; - isFirstWordStarted = false; - isFirstWordEnded = false; - isDoLastWord = false; - - //blank out first word - for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++) - szFirstWord[i] = '\0'; - } - } - - // save the last processed characters - if ((ch > 0) && !isspacechar(ch)) { - chPrevPrevPrev = chPrevPrev; - chPrevPrev = chPrev; - chPrev = ch; - } - } - - //close folds on the last line - without this a 'phantom' - //fold can appear when an open fold is on the last line - //this can occur because functions and labels don't have an explicit end - if (lineCurrent >= lastLine) { - int lev = 0; - lev |= SC_FOLDLEVELWHITEFLAG; - styler.SetLevel(lineCurrent, lev); - } - -} - -static const char * const powerProWordLists[] = { - "Keyword list 1", - "Keyword list 2", - "Keyword list 3", - "Keyword list 4", - 0, - }; - -static void ColourisePowerProDocWrapper(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], - Accessor &styler) { - ColourisePowerProDoc(startPos, length, initStyle, keywordlists, styler, false); -} - -LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists); - - |