diff options
Diffstat (limited to 'lexers/LexMySQL.cxx')
| -rw-r--r-- | lexers/LexMySQL.cxx | 574 | 
1 files changed, 0 insertions, 574 deletions
| diff --git a/lexers/LexMySQL.cxx b/lexers/LexMySQL.cxx deleted file mode 100644 index 7ba52a3e2..000000000 --- a/lexers/LexMySQL.cxx +++ /dev/null @@ -1,574 +0,0 @@ -/** - * Scintilla source code edit control - * @file LexMySQL.cxx - * Lexer for MySQL - * - * Improved by Mike Lischke <mike.lischke@oracle.com> - * Adopted from LexSQL.cxx by Anders Karlsson <anders@mysql.com> - * Original work by Neil Hodgson <neilh@scintilla.org> - * Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> - * The License.txt file describes the conditions under which this software may be distributed. - */ - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <stdarg.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 IsAWordChar(int ch) { -	return (ch < 0x80) && (isalnum(ch) || ch == '_'); -} - -static inline bool IsAWordStart(int ch) { -	return (ch < 0x80) && (isalpha(ch) || ch == '_'); -} - -static inline bool IsANumberChar(int ch) { -	// Not exactly following number definition (several dots are seen as OK, etc.) -	// but probably enough in most cases. -	return (ch < 0x80) && -	        (isdigit(ch) || toupper(ch) == 'E' || -             ch == '.' || ch == '-' || ch == '+'); -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Check if the current content context represent a keyword and set the context state if so. - */ -static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState) -{ -  Sci_Position length = sc.LengthCurrent() + 1; // +1 for the next char -  char* s = new char[length]; -  sc.GetCurrentLowered(s, length); -  if (keywordlists[0]->InList(s)) -    sc.ChangeState(SCE_MYSQL_MAJORKEYWORD | activeState); -  else -    if (keywordlists[1]->InList(s)) -      sc.ChangeState(SCE_MYSQL_KEYWORD | activeState); -    else -      if (keywordlists[2]->InList(s)) -        sc.ChangeState(SCE_MYSQL_DATABASEOBJECT | activeState); -      else -        if (keywordlists[3]->InList(s)) -          sc.ChangeState(SCE_MYSQL_FUNCTION | activeState); -        else -          if (keywordlists[5]->InList(s)) -            sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD | activeState); -          else -            if (keywordlists[6]->InList(s)) -              sc.ChangeState(SCE_MYSQL_USER1 | activeState); -            else -              if (keywordlists[7]->InList(s)) -                sc.ChangeState(SCE_MYSQL_USER2 | activeState); -              else -                if (keywordlists[8]->InList(s)) -                  sc.ChangeState(SCE_MYSQL_USER3 | activeState); -  delete [] s; -} - -//-------------------------------------------------------------------------------------------------- - -#define HIDDENCOMMAND_STATE 0x40 // Offset for states within a hidden command. -#define MASKACTIVE(style) (style & ~HIDDENCOMMAND_STATE) - -static void SetDefaultState(StyleContext& sc, int activeState) -{ -  if (activeState == 0) -    sc.SetState(SCE_MYSQL_DEFAULT); -  else -    sc.SetState(SCE_MYSQL_HIDDENCOMMAND); -} - -static void ForwardDefaultState(StyleContext& sc, int activeState) -{ -  if (activeState == 0) -    sc.ForwardSetState(SCE_MYSQL_DEFAULT); -  else -    sc.ForwardSetState(SCE_MYSQL_HIDDENCOMMAND); -} - -static void ColouriseMySQLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *keywordlists[], -                            Accessor &styler) -{ -	StyleContext sc(startPos, length, initStyle, styler, 127); -  int activeState = (initStyle == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : initStyle & HIDDENCOMMAND_STATE; - -	for (; sc.More(); sc.Forward()) -  { -		// Determine if the current state should terminate. -		switch (MASKACTIVE(sc.state)) -    { -      case SCE_MYSQL_OPERATOR: -        SetDefaultState(sc, activeState); -        break; -      case SCE_MYSQL_NUMBER: -        // We stop the number definition on non-numerical non-dot non-eE non-sign char. -        if (!IsANumberChar(sc.ch)) -          SetDefaultState(sc, activeState); -        break; -      case SCE_MYSQL_IDENTIFIER: -        // Switch from identifier to keyword state and open a new state for the new char. -        if (!IsAWordChar(sc.ch)) -        { -          CheckForKeyword(sc, keywordlists, activeState); - -          // Additional check for function keywords needed. -          // A function name must be followed by an opening parenthesis. -          if (MASKACTIVE(sc.state) == SCE_MYSQL_FUNCTION && sc.ch != '(') -          { -            if (activeState > 0) -              sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND); -            else -              sc.ChangeState(SCE_MYSQL_DEFAULT); -          } - -          SetDefaultState(sc, activeState); -        } -        break; -      case SCE_MYSQL_VARIABLE: -        if (!IsAWordChar(sc.ch)) -          SetDefaultState(sc, activeState); -        break; -      case SCE_MYSQL_SYSTEMVARIABLE: -        if (!IsAWordChar(sc.ch)) -        { -          Sci_Position length = sc.LengthCurrent() + 1; -          char* s = new char[length]; -          sc.GetCurrentLowered(s, length); - -          // Check for known system variables here. -          if (keywordlists[4]->InList(&s[2])) -            sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE | activeState); -          delete [] s; - -          SetDefaultState(sc, activeState); -        } -        break; -      case SCE_MYSQL_QUOTEDIDENTIFIER: -        if (sc.ch == '`') -        { -          if (sc.chNext == '`') -            sc.Forward();	// Ignore it -          else -            ForwardDefaultState(sc, activeState); -				} -  			break; -      case SCE_MYSQL_COMMENT: -        if (sc.Match('*', '/')) -        { -          sc.Forward(); -          ForwardDefaultState(sc, activeState); -        } -        break; -      case SCE_MYSQL_COMMENTLINE: -        if (sc.atLineStart) -          SetDefaultState(sc, activeState); -        break; -      case SCE_MYSQL_SQSTRING: -        if (sc.ch == '\\') -          sc.Forward(); // Escape sequence -        else -          if (sc.ch == '\'') -          { -            // End of single quoted string reached? -            if (sc.chNext == '\'') -              sc.Forward(); -            else -              ForwardDefaultState(sc, activeState); -          } -        break; -      case SCE_MYSQL_DQSTRING: -        if (sc.ch == '\\') -          sc.Forward(); // Escape sequence -        else -          if (sc.ch == '\"') -          { -            // End of single quoted string reached? -            if (sc.chNext == '\"') -              sc.Forward(); -            else -              ForwardDefaultState(sc, activeState); -          } -        break; -      case SCE_MYSQL_PLACEHOLDER: -        if (sc.Match('}', '>')) -        { -          sc.Forward(); -          ForwardDefaultState(sc, activeState); -        } -        break; -    } - -    if (sc.state == SCE_MYSQL_HIDDENCOMMAND && sc.Match('*', '/')) -    { -      activeState = 0; -      sc.Forward(); -      ForwardDefaultState(sc, activeState); -    } - -    // Determine if a new state should be entered. -    if (sc.state == SCE_MYSQL_DEFAULT || sc.state == SCE_MYSQL_HIDDENCOMMAND) -    { -      switch (sc.ch) -      { -        case '@': -          if (sc.chNext == '@') -          { -            sc.SetState(SCE_MYSQL_SYSTEMVARIABLE | activeState); -            sc.Forward(2); // Skip past @@. -          } -          else -            if (IsAWordStart(sc.ch)) -            { -              sc.SetState(SCE_MYSQL_VARIABLE | activeState); -              sc.Forward(); // Skip past @. -            } -            else -              sc.SetState(SCE_MYSQL_OPERATOR | activeState); -          break; -        case '`': -          sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER | activeState); -          break; -        case '#': -          sc.SetState(SCE_MYSQL_COMMENTLINE | activeState); -          break; -        case '\'': -          sc.SetState(SCE_MYSQL_SQSTRING | activeState); -          break; -        case '\"': -          sc.SetState(SCE_MYSQL_DQSTRING | activeState); -          break; -        default: -          if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) -            sc.SetState(SCE_MYSQL_NUMBER | activeState); -          else -            if (IsAWordStart(sc.ch)) -              sc.SetState(SCE_MYSQL_IDENTIFIER | activeState); -            else -              if (sc.Match('/', '*')) -              { -                sc.SetState(SCE_MYSQL_COMMENT | activeState); - -                // Skip first char of comment introducer and check for hidden command. -                // The second char is skipped by the outer loop. -                sc.Forward(); -                if (sc.GetRelativeCharacter(1) == '!') -                { -                  // Version comment found. Skip * now. -                  sc.Forward(); -                  activeState = HIDDENCOMMAND_STATE; -                  sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND); -                } -              } -              else if (sc.Match('<', '{')) -              { -                sc.SetState(SCE_MYSQL_PLACEHOLDER | activeState); -              } -              else -                if (sc.Match("--")) -                { -                  // Special MySQL single line comment. -                  sc.SetState(SCE_MYSQL_COMMENTLINE | activeState); -                  sc.Forward(2); - -                  // Check the third character too. It must be a space or EOL. -                  if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r') -                    sc.ChangeState(SCE_MYSQL_OPERATOR | activeState); -                } -                else -                  if (isoperator(static_cast<char>(sc.ch))) -                    sc.SetState(SCE_MYSQL_OPERATOR | activeState); -      } -    } -  } - -  // Do a final check for keywords if we currently have an identifier, to highlight them -  // also at the end of a line. -  if (sc.state == SCE_MYSQL_IDENTIFIER) -  { -    CheckForKeyword(sc, keywordlists, activeState); - -    // Additional check for function keywords needed. -    // A function name must be followed by an opening parenthesis. -    if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(') -      SetDefaultState(sc, activeState); -  } - -  sc.Complete(); -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Helper function to determine if we have a foldable comment currently. - */ -static bool IsStreamCommentStyle(int style) -{ -	return MASKACTIVE(style) == SCE_MYSQL_COMMENT; -} - -//-------------------------------------------------------------------------------------------------- - -/** - * Code copied from StyleContext and modified to work here. Should go into Accessor as a - * companion to Match()... - */ -static bool MatchIgnoreCase(Accessor &styler, Sci_Position currentPos, const char *s) -{ -  for (Sci_Position n = 0; *s; n++) -  { -    if (*s != tolower(styler.SafeGetCharAt(currentPos + n))) -      return false; -    s++; -  } -  return true; -} - -//-------------------------------------------------------------------------------------------------- - -// Store both the current line's fold level and the next lines in the -// level store to make it easy to pick up with each increment. -static void FoldMySQLDoc(Sci_PositionU startPos, Sci_Position length, int initStyle, WordList *[], Accessor &styler) -{ -	bool foldComment = styler.GetPropertyInt("fold.comment") != 0; -	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0; -	bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0; - -	int visibleChars = 0; -	Sci_Position lineCurrent = styler.GetLine(startPos); -	int levelCurrent = SC_FOLDLEVELBASE; -	if (lineCurrent > 0) -		levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16; -	int levelNext = levelCurrent; - -	int styleNext = styler.StyleAt(startPos); -	int style = initStyle; -  int activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE; - -  bool endPending = false; -	bool whenPending = false; -	bool elseIfPending = false; - -  char nextChar = styler.SafeGetCharAt(startPos); -  for (Sci_PositionU i = startPos; length > 0; i++, length--) -  { -		int stylePrev = style; -    int lastActiveState = activeState; -		style = styleNext; -		styleNext = styler.StyleAt(i + 1); -    activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE; - -    char currentChar = nextChar; -    nextChar = styler.SafeGetCharAt(i + 1); -		bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n'); - -    switch (MASKACTIVE(style)) -    { -      case SCE_MYSQL_COMMENT: -        if (foldComment) -        { -          // Multiline comment style /* .. */ just started or is still in progress. -          if (IsStreamCommentStyle(style) && !IsStreamCommentStyle(stylePrev)) -            levelNext++; -        } -        break; -      case SCE_MYSQL_COMMENTLINE: -        if (foldComment) -        { -          // Not really a standard, but we add support for single line comments -          // with special curly braces syntax as foldable comments too. -          // MySQL needs -- comments to be followed by space or control char -          if (styler.Match(i, "--")) -          { -            char chNext2 = styler.SafeGetCharAt(i + 2); -            char chNext3 = styler.SafeGetCharAt(i + 3); -            if (chNext2 == '{' || chNext3 == '{') -              levelNext++; -            else -              if (chNext2 == '}' || chNext3 == '}') -                levelNext--; -          } -        } -        break; -      case SCE_MYSQL_HIDDENCOMMAND: -        /* -        if (endPending) -        { -          // A conditional command is not a white space so it should end the current block -          // before opening a new one. -          endPending = false; -          levelNext--; -          if (levelNext < SC_FOLDLEVELBASE) -            levelNext = SC_FOLDLEVELBASE; -        } -        }*/ -        if (activeState != lastActiveState) -          levelNext++; -        break; -      case SCE_MYSQL_OPERATOR: -        if (endPending) -        { -          endPending = false; -          levelNext--; -          if (levelNext < SC_FOLDLEVELBASE) -            levelNext = SC_FOLDLEVELBASE; -        } -        if (currentChar == '(') -          levelNext++; -        else -          if (currentChar == ')') -          { -            levelNext--; -            if (levelNext < SC_FOLDLEVELBASE) -              levelNext = SC_FOLDLEVELBASE; -          } -        break; -      case SCE_MYSQL_MAJORKEYWORD: -      case SCE_MYSQL_KEYWORD: -      case SCE_MYSQL_FUNCTION: -      case SCE_MYSQL_PROCEDUREKEYWORD: -        // Reserved and other keywords. -        if (style != stylePrev) -        { -          // END decreases the folding level, regardless which keyword follows. -          bool endFound = MatchIgnoreCase(styler, i, "end"); -          if (endPending) -          { -            levelNext--; -            if (levelNext < SC_FOLDLEVELBASE) -              levelNext = SC_FOLDLEVELBASE; -          } -          else -            if (!endFound) -            { -              if (MatchIgnoreCase(styler, i, "begin")) -                levelNext++; -              else -              { -                if (!foldOnlyBegin) -                { -                  bool whileFound = MatchIgnoreCase(styler, i, "while"); -                  bool loopFound = MatchIgnoreCase(styler, i, "loop"); -                  bool repeatFound = MatchIgnoreCase(styler, i, "repeat"); -                  bool caseFound = MatchIgnoreCase(styler, i, "case"); - -                  if (whileFound || loopFound || repeatFound || caseFound) -                    levelNext++; -                  else -                  { -                    // IF alone does not increase the fold level as it is also used in non-block'ed -                    // code like DROP PROCEDURE blah IF EXISTS. -                    // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch). -                    if (MatchIgnoreCase(styler, i, "then")) -                    { -                      if (!elseIfPending && !whenPending) -                        levelNext++; -                      else -                      { -                        elseIfPending = false; -                        whenPending = false; -                      } -                    } -                    else -                    { -                      // Neither of if/then/while/loop/repeat/case, so check for -                      // sub parts of IF and CASE. -                      if (MatchIgnoreCase(styler, i, "elseif")) -                        elseIfPending = true; -                      if (MatchIgnoreCase(styler, i, "when")) -                        whenPending = true; -                    } -                  } -                } -              } -            } - -          // Keep the current end state for the next round. -          endPending = endFound; -        } -        break; - -      default: -        if (!isspacechar(currentChar) && endPending) -        { -          // END followed by a non-whitespace character (not covered by other cases like identifiers) -          // also should end a folding block. Typical case: END followed by self defined delimiter. -          levelNext--; -          if (levelNext < SC_FOLDLEVELBASE) -            levelNext = SC_FOLDLEVELBASE; -        } -        break; -    } - -    // Go up one level if we just ended a multi line comment. -    if (IsStreamCommentStyle(stylePrev) && !IsStreamCommentStyle(style)) -    { -      levelNext--; -      if (levelNext < SC_FOLDLEVELBASE) -        levelNext = SC_FOLDLEVELBASE; -    } - -    if (activeState == 0 && lastActiveState != 0) -    { -      // Decrease fold level when we left a hidden command. -      levelNext--; -      if (levelNext < SC_FOLDLEVELBASE) -        levelNext = SC_FOLDLEVELBASE; -    } - -    if (atEOL) -    { -      // Apply the new folding level to this line. -      // Leave pending states as they are otherwise a line break will de-sync -      // code folding and valid syntax. -      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); - -      lineCurrent++; -      levelCurrent = levelNext; -      visibleChars = 0; -    } - -		if (!isspacechar(currentChar)) -      visibleChars++; -  } -} - -//-------------------------------------------------------------------------------------------------- - -static const char * const mysqlWordListDesc[] = { -	"Major Keywords", -	"Keywords", -	"Database Objects", -	"Functions", -	"System Variables", -	"Procedure keywords", -	"User Keywords 1", -	"User Keywords 2", -	"User Keywords 3", -	0 -}; - -LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc); | 
