Example #1
0
static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
                WordList *keywordlists[], Accessor &styler) {

  StyleContext sc(startPos, length, initStyle, styler);
  WordList &reservedWords = *keywordlists[0];
  WordList &erlangBIFs = *keywordlists[1];
  WordList &erlangPreproc = *keywordlists[2];
  WordList &erlangModulesAtt = *keywordlists[3];
  WordList &erlangDoc = *keywordlists[4];
  WordList &erlangDocMacro = *keywordlists[5];
  int radix_digits = 0;
  int exponent_digits = 0;
  atom_parse_state_t parse_state = STATE_NULL;
  atom_parse_state_t old_parse_state = STATE_NULL;
  bool to_late_to_comment = false;
  char cur[100];
  int old_style = SCE_ERLANG_DEFAULT;

  styler.StartAt(startPos);

  for (; sc.More(); sc.Forward()) {
    int style = SCE_ERLANG_DEFAULT;
    if (STATE_NULL != parse_state) {

      switch (parse_state) {

        case STATE_NULL : sc.SetState(SCE_ERLANG_DEFAULT); break;

      /* COMMENTS ------------------------------------------------------*/
        case COMMENT : {
          if (sc.ch != '%') {
            to_late_to_comment = true;
          } else if (!to_late_to_comment && sc.ch == '%') {
            // Switch to comment level 2 (Function)
            sc.ChangeState(SCE_ERLANG_COMMENT_FUNCTION);
            old_style = SCE_ERLANG_COMMENT_FUNCTION;
            parse_state = COMMENT_FUNCTION;
            sc.Forward();
          }
        }
        // V--- Falling through!
        case COMMENT_FUNCTION : {
          if (sc.ch != '%') {
            to_late_to_comment = true;
          } else if (!to_late_to_comment && sc.ch == '%') {
            // Switch to comment level 3 (Module)
            sc.ChangeState(SCE_ERLANG_COMMENT_MODULE);
            old_style = SCE_ERLANG_COMMENT_MODULE;
            parse_state = COMMENT_MODULE;
            sc.Forward();
          }
        }
        // V--- Falling through!
        case COMMENT_MODULE : {
          if (parse_state != COMMENT) {
            // Search for comment documentation
            if (sc.chNext == '@') {
              old_parse_state = parse_state;
              parse_state = ('{' == sc.ch)
                      ? COMMENT_DOC_MACRO
                      : COMMENT_DOC;
              sc.ForwardSetState(sc.state);
            }
          }

          // All comments types fall here.
          if (sc.atLineEnd) {
            to_late_to_comment = false;
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

        case COMMENT_DOC :
        // V--- Falling through!
        case COMMENT_DOC_MACRO : {

          if (!isalnum(sc.ch)) {
            // Try to match documentation comment
            sc.GetCurrent(cur, sizeof(cur));

            if (parse_state == COMMENT_DOC_MACRO
              && erlangDocMacro.InList(cur)) {
                sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
                while (sc.ch != '}' && !sc.atLineEnd)
                  sc.Forward();
            } else if (erlangDoc.InList(cur)) {
              sc.ChangeState(SCE_ERLANG_COMMENT_DOC);
            } else {
              sc.ChangeState(old_style);
            }

            // Switch back to old state
            sc.SetState(old_style);
            parse_state = old_parse_state;
          }

          if (sc.atLineEnd) {
            to_late_to_comment = false;
            sc.ChangeState(old_style);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* -------------------------------------------------------------- */
      /* Atoms ---------------------------------------------------------*/
        case ATOM_UNQUOTED : {
          if ('@' == sc.ch){
            parse_state = NODE_NAME_UNQUOTED;
          } else if (sc.ch == ':') {
            // Searching for module name
            if (sc.chNext == ' ') {
              // error
              sc.ChangeState(SCE_ERLANG_UNKNOWN);
              parse_state = STATE_NULL;
            } else {
              sc.Forward();
              if (isalnum(sc.ch))  {
                sc.GetCurrent(cur, sizeof(cur));
                sc.ChangeState(SCE_ERLANG_MODULES);
                sc.SetState(SCE_ERLANG_MODULES);
              }
            }
          } else if (!IsAWordChar(sc.ch)) {

            sc.GetCurrent(cur, sizeof(cur));
            if (reservedWords.InList(cur)) {
              style = SCE_ERLANG_KEYWORD;
            } else if (erlangBIFs.InList(cur)
                  && strcmp(cur,"erlang:")){
              style = SCE_ERLANG_BIFS;
            } else if (sc.ch == '(' || '/' == sc.ch){
              style = SCE_ERLANG_FUNCTION_NAME;
            } else {
              style = SCE_ERLANG_ATOM;
            }

            sc.ChangeState(style);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }

        } break;

        case ATOM_QUOTED : {
          if ( '@' == sc.ch ){
            parse_state = NODE_NAME_QUOTED;
          } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
            sc.ChangeState(SCE_ERLANG_ATOM);
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* -------------------------------------------------------------- */
      /* Node names ----------------------------------------------------*/
        case NODE_NAME_UNQUOTED : {
          if ('@' == sc.ch) {
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          } else if (!IsAWordChar(sc.ch)) {
            sc.ChangeState(SCE_ERLANG_NODE_NAME);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

        case NODE_NAME_QUOTED : {
          if ('@' == sc.ch) {
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          } else if ('\'' == sc.ch && '\\' != sc.chPrev) {
            sc.ChangeState(SCE_ERLANG_NODE_NAME_QUOTED);
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* -------------------------------------------------------------- */
      /* Records -------------------------------------------------------*/
        case RECORD_START : {
          if ('\'' == sc.ch) {
            parse_state = RECORD_QUOTED;
          } else if (isalpha(sc.ch) && islower(sc.ch)) {
            parse_state = RECORD_UNQUOTED;
          } else { // error
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

        case RECORD_UNQUOTED : {
          if (!IsAWordChar(sc.ch)) {
            sc.ChangeState(SCE_ERLANG_RECORD);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

        case RECORD_QUOTED : {
          if ('\'' == sc.ch && '\\' != sc.chPrev) {
            sc.ChangeState(SCE_ERLANG_RECORD_QUOTED);
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* -------------------------------------------------------------- */
      /* Macros --------------------------------------------------------*/
        case MACRO_START : {
          if ('\'' == sc.ch) {
            parse_state = MACRO_QUOTED;
          } else if (isalpha(sc.ch)) {
            parse_state = MACRO_UNQUOTED;
          } else { // error
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

        case MACRO_UNQUOTED : {
          if (!IsAWordChar(sc.ch)) {
            sc.ChangeState(SCE_ERLANG_MACRO);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

        case MACRO_QUOTED : {
          if ('\'' == sc.ch && '\\' != sc.chPrev) {
            sc.ChangeState(SCE_ERLANG_MACRO_QUOTED);
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* -------------------------------------------------------------- */
      /* Numerics ------------------------------------------------------*/
      /* Simple integer */
        case NUMERAL_START : {
          if (isdigit(sc.ch)) {
            radix_digits *= 10;
            radix_digits += sc.ch - '0'; // Assuming ASCII here!
          } else if ('#' == sc.ch) {
            if (2 > radix_digits || 36 < radix_digits) {
              sc.SetState(SCE_ERLANG_DEFAULT);
              parse_state = STATE_NULL;
            } else {
              parse_state = NUMERAL_BASE_VALUE;
            }
          } else if ('.' == sc.ch && isdigit(sc.chNext)) {
            radix_digits = 0;
            parse_state = NUMERAL_FLOAT;
          } else if ('e' == sc.ch || 'E' == sc.ch) {
            exponent_digits = 0;
            parse_state = NUMERAL_EXPONENT;
          } else {
            radix_digits = 0;
            sc.ChangeState(SCE_ERLANG_NUMBER);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* Integer in other base than 10 (x#yyy) */
        case NUMERAL_BASE_VALUE : {
          if (!is_radix(radix_digits,sc.ch)) {
            radix_digits = 0;

            if (!isalnum(sc.ch))
              sc.ChangeState(SCE_ERLANG_NUMBER);

            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* Float (x.yyy) */
        case NUMERAL_FLOAT : {
          if ('e' == sc.ch || 'E' == sc.ch) {
            exponent_digits = 0;
            parse_state = NUMERAL_EXPONENT;
          } else if (!isdigit(sc.ch)) {
            sc.ChangeState(SCE_ERLANG_NUMBER);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      /* Exponent, either integer or float (xEyy, x.yyEzzz) */
        case NUMERAL_EXPONENT : {
          if (('-' == sc.ch || '+' == sc.ch)
              && (isdigit(sc.chNext))) {
            sc.Forward();
          } else if (!isdigit(sc.ch)) {
            if (0 < exponent_digits)
              sc.ChangeState(SCE_ERLANG_NUMBER);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          } else {
            ++exponent_digits;
          }
        } break;

      /* -------------------------------------------------------------- */
      /* Preprocessor --------------------------------------------------*/
        case PREPROCESSOR : {
          if (!IsAWordChar(sc.ch)) {

            sc.GetCurrent(cur, sizeof(cur));
            if (erlangPreproc.InList(cur)) {
              style = SCE_ERLANG_PREPROC;
            } else if (erlangModulesAtt.InList(cur)) {
              style = SCE_ERLANG_MODULES_ATT;
            }

            sc.ChangeState(style);
            sc.SetState(SCE_ERLANG_DEFAULT);
            parse_state = STATE_NULL;
          }
        } break;

      }

    } /* End of : STATE_NULL != parse_state */
    else
    {
      switch (sc.state) {
        case SCE_ERLANG_VARIABLE : {
          if (!IsAWordChar(sc.ch))
            sc.SetState(SCE_ERLANG_DEFAULT);
        } break;
        case SCE_ERLANG_STRING : {
           if (sc.ch == '\"' && sc.chPrev != '\\')
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
        } break;
        case SCE_ERLANG_COMMENT : {
           if (sc.atLineEnd)
            sc.SetState(SCE_ERLANG_DEFAULT);
        } break;
        case SCE_ERLANG_CHARACTER : {
          if (sc.chPrev == '\\') {
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
          } else if (sc.ch != '\\') {
            sc.ForwardSetState(SCE_ERLANG_DEFAULT);
          }
        } break;
        case SCE_ERLANG_OPERATOR : {
          if (sc.chPrev == '.') {
            if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
              || sc.ch == '^') {
              sc.ForwardSetState(SCE_ERLANG_DEFAULT);
            } else if (sc.ch == '\'') {
              sc.ForwardSetState(SCE_ERLANG_DEFAULT);
            } else {
              sc.SetState(SCE_ERLANG_DEFAULT);
            }
          } else {
            sc.SetState(SCE_ERLANG_DEFAULT);
          }
        } break;
      }
    }

    if (sc.state == SCE_ERLANG_DEFAULT) {
      bool no_new_state = false;

      switch (sc.ch) {
        case '\"' : sc.SetState(SCE_ERLANG_STRING); break;
        case '$' : sc.SetState(SCE_ERLANG_CHARACTER); break;
        case '%' : {
          parse_state = COMMENT;
          sc.SetState(SCE_ERLANG_COMMENT);
        } break;
        case '#' : {
          parse_state = RECORD_START;
          sc.SetState(SCE_ERLANG_UNKNOWN);
        } break;
        case '?' : {
          parse_state = MACRO_START;
          sc.SetState(SCE_ERLANG_UNKNOWN);
        } break;
        case '\'' : {
          parse_state = ATOM_QUOTED;
          sc.SetState(SCE_ERLANG_UNKNOWN);
        } break;
        case '+' :
        case '-' : {
          if (IsADigit(sc.chNext)) {
            parse_state = NUMERAL_START;
            radix_digits = 0;
            sc.SetState(SCE_ERLANG_UNKNOWN);
          } else if (sc.ch != '+') {
            parse_state = PREPROCESSOR;
            sc.SetState(SCE_ERLANG_UNKNOWN);
          }
        } break;
        default : no_new_state = true;
      }

      if (no_new_state) {
        if (isdigit(sc.ch)) {
          parse_state = NUMERAL_START;
          radix_digits = sc.ch - '0';
          sc.SetState(SCE_ERLANG_UNKNOWN);
        } else if (isupper(sc.ch) || '_' == sc.ch) {
          sc.SetState(SCE_ERLANG_VARIABLE);
        } else if (isalpha(sc.ch)) {
          parse_state = ATOM_UNQUOTED;
          sc.SetState(SCE_ERLANG_UNKNOWN);
        } else if (isoperator(static_cast<char>(sc.ch))
              || sc.ch == '\\') {
          sc.SetState(SCE_ERLANG_OPERATOR);
        }
      }
    }

  }
  sc.Complete();
}
Example #2
0
inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
{
	char ch;
	
	if( could_fail )
	{
		cur++;
		if( cur >= one_too_much )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
			return false; // STOP
		}
		
		ch = styler.SafeGetCharAt( cur );
		if( ch != '-' )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
			styler.StartSegment( cur );
			return true;
		}

		cur++;
		if( cur >= one_too_much )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
			return false; // STOP
		}
		
		ch = styler.SafeGetCharAt( cur );
		if( ( ch != ' ' ) && ( ch != '\t' ) )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
			styler.StartSegment( cur );
			return true;
		}
	}

	// Wait for end of line
	bool fifteen_found = false;

	for( ; ; )
	{
		cur++;

		if( cur >= one_too_much )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
			return false; // STOP
		}

		ch = styler.SafeGetCharAt( cur );
		if( fifteen_found )
		{
/*
			if( ch == '\012' )
			{
				// One newline on Windows (015, 012)
			}
			else
			{
				// One newline on MAC (015) and another char
			}
*/
			cur--;
			styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
			styler.StartSegment( cur );
			return true;
		}
		else
		{
			if( ch == '\015' )
			{
				fifteen_found = true;	
			}
			else if( ch == '\012' )
			{
				// One newline on Linux (012)
				styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_LINE );
				styler.StartSegment( cur );
				return true;
			}
		}
	}
}
Example #3
0
static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor & styler )
{
	styler.StartAt( startPos );
	styler.StartSegment( startPos );

	unsigned int & cur = startPos;
	const unsigned int one_too_much = startPos + length;

	int state = initStyle;

	for( ; ; )
	{
		switch( state )
		{
		case SCE_OPAL_KEYWORD:
		case SCE_OPAL_SORT:
			if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
			state = SCE_OPAL_DEFAULT;
			break;

		case SCE_OPAL_INTEGER:
			if( !HandleInteger( cur, one_too_much, styler ) ) return;
			state = SCE_OPAL_DEFAULT;
			break;

		case SCE_OPAL_COMMENT_BLOCK:
			if( !HandleCommentBlock( cur, one_too_much, styler, false ) ) return;
			state = SCE_OPAL_DEFAULT;
			break;

		case SCE_OPAL_COMMENT_LINE:
			if( !HandleCommentLine( cur, one_too_much, styler, false ) ) return;
			state = SCE_OPAL_DEFAULT;
			break;

		case SCE_OPAL_STRING:
			if( !HandleString( cur, one_too_much, styler ) ) return;
			state = SCE_OPAL_DEFAULT;
			break;
			
		default: // SCE_OPAL_DEFAULT:
			{
				char ch = styler.SafeGetCharAt( cur );
				
				switch( ch )
				{
				// String
				case '"':
					if( !HandleString( cur, one_too_much, styler ) ) return;
					break;

				// Comment block
				case '/':
					if( !HandleCommentBlock( cur, one_too_much, styler, true ) ) return;
					break;

				// Comment line
				case '-':
					if( !HandleCommentLine( cur, one_too_much, styler, true ) ) return;
					break;

				// Par
				case '(':
				case ')':
				case '[':
				case ']':
				case '{':
				case '}':
					if( !HandlePar( cur, styler ) ) return;
					break;

				// Whitespace
				case ' ':
				case '\t':
				case '\015':
				case '\012':
					if( !HandleSpace( cur, one_too_much, styler ) ) return;
					break;
				
				default:
					{
						// Integer
						if( isdigit( ch ) )
						{
							if( !HandleInteger( cur, one_too_much, styler ) ) return;
						}

						// Keyword
						else if( islower( ch ) || isupper( ch ) )
						{
							if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
							
						}

						// Skip
						else
						{
							if( !HandleSkip( cur, one_too_much, styler ) ) return;
						}
					}
				}

				break;
			}
		}
	}
}
Example #4
0
static void ColouriseMSSQLDoc(unsigned int startPos, int length,
                              int initStyle, WordList *keywordlists[], Accessor &styler) {


  styler.StartAt(startPos);

  bool fold = styler.GetPropertyInt("fold") != 0;
  int lineCurrent = styler.GetLine(startPos);
  int spaceFlags = 0;

  int state = initStyle;
  int prevState = initStyle;
  char chPrev = ' ';
  char chNext = styler[startPos];
  styler.StartSegment(startPos);
  unsigned int lengthDoc = startPos + length;
  for (unsigned int i = startPos; i < lengthDoc; i++) {
    char ch = chNext;
    chNext = styler.SafeGetCharAt(i + 1);

    if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
      int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
      int lev = indentCurrent;
      if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
        // Only non whitespace lines can be headers
        int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
        if (indentCurrent < (indentNext & ~SC_FOLDLEVELWHITEFLAG)) {
          lev |= SC_FOLDLEVELHEADERFLAG;
        }
      }
      if (fold) {
        styler.SetLevel(lineCurrent, lev);
      }
    }

    if (styler.IsLeadByte(ch)) {
      chNext = styler.SafeGetCharAt(i + 2);
      chPrev = ' ';
      i += 1;
      continue;
    }

    // When the last char isn't part of the state (have to deal with it too)...
    if ( (state == SCE_MSSQL_IDENTIFIER) ||
                    (state == SCE_MSSQL_STORED_PROCEDURE) ||
                    (state == SCE_MSSQL_DATATYPE) ||
                    //~ (state == SCE_MSSQL_COLUMN_NAME) ||
                    (state == SCE_MSSQL_FUNCTION) ||
                    //~ (state == SCE_MSSQL_GLOBAL_VARIABLE) ||
                    (state == SCE_MSSQL_VARIABLE)) {
      if (!iswordchar(ch)) {
        int stateTmp;

                if ((state == SCE_MSSQL_VARIABLE) || (state == SCE_MSSQL_COLUMN_NAME)) {
                    styler.ColourTo(i - 1, state);
          stateTmp = state;
                } else
                    stateTmp = classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);

        prevState = state;

        if (stateTmp == SCE_MSSQL_IDENTIFIER || stateTmp == SCE_MSSQL_VARIABLE)
          state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
        else
          state = SCE_MSSQL_DEFAULT;
      }
    } else if (state == SCE_MSSQL_LINE_COMMENT) {
      if (ch == '\r' || ch == '\n') {
        styler.ColourTo(i - 1, state);
        prevState = state;
        state = SCE_MSSQL_DEFAULT;
      }
    } else if (state == SCE_MSSQL_GLOBAL_VARIABLE) {
      if ((ch != '@') && !iswordchar(ch)) {
        classifyWordSQL(styler.GetStartSegment(), i - 1, keywordlists, styler, state, prevState);
        prevState = state;
        state = SCE_MSSQL_DEFAULT;
      }
    }

    // If is the default or one of the above succeeded
    if (state == SCE_MSSQL_DEFAULT || state == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
      if (iswordstart(ch)) {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
        state = SCE_MSSQL_IDENTIFIER;
      } else if (ch == '/' && chNext == '*') {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
        state = SCE_MSSQL_COMMENT;
      } else if (ch == '-' && chNext == '-') {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
        state = SCE_MSSQL_LINE_COMMENT;
      } else if (ch == '\'') {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
        state = SCE_MSSQL_STRING;
      } else if (ch == '"') {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
        state = SCE_MSSQL_COLUMN_NAME;
      } else if (ch == '[') {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
        state = SCE_MSSQL_COLUMN_NAME_2;
      } else if (isoperator(ch)) {
        styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        styler.ColourTo(i, SCE_MSSQL_OPERATOR);
                //~ style = SCE_MSSQL_DEFAULT;
        prevState = state;
        state = SCE_MSSQL_DEFAULT;
      } else if (ch == '@') {
                styler.ColourTo(i - 1, SCE_MSSQL_DEFAULT);
        prevState = state;
                if (chNext == '@') {
                    state = SCE_MSSQL_GLOBAL_VARIABLE;
//                    i += 2;
                } else
                    state = SCE_MSSQL_VARIABLE;
            }


    // When the last char is part of the state...
    } else if (state == SCE_MSSQL_COMMENT) {
        if (ch == '/' && chPrev == '*') {
          if (((i > (styler.GetStartSegment() + 2)) || ((initStyle == SCE_MSSQL_COMMENT) &&
              (styler.GetStartSegment() == startPos)))) {
            styler.ColourTo(i, state);
            //~ state = SCE_MSSQL_COMMENT;
          prevState = state;
                        state = SCE_MSSQL_DEFAULT;
          }
        }
      } else if (state == SCE_MSSQL_STRING) {
        if (ch == '\'') {
          if ( chNext == '\'' ) {
            i++;
          ch = chNext;
          chNext = styler.SafeGetCharAt(i + 1);
          } else {
            styler.ColourTo(i, state);
          prevState = state;
            state = SCE_MSSQL_DEFAULT;
          //i++;
          }
        //ch = chNext;
        //chNext = styler.SafeGetCharAt(i + 1);
        }
      } else if (state == SCE_MSSQL_COLUMN_NAME) {
        if (ch == '"') {
          if (chNext == '"') {
            i++;
          ch = chNext;
          chNext = styler.SafeGetCharAt(i + 1);
        } else {
                    styler.ColourTo(i, state);
          prevState = state;
          state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
          //i++;
                }
                }
    } else if (state == SCE_MSSQL_COLUMN_NAME_2) {
      if (ch == ']') {
                styler.ColourTo(i, state);
        prevState = state;
                state = SCE_MSSQL_DEFAULT_PREF_DATATYPE;
                //i++;
      }
    }

    chPrev = ch;
  }
  styler.ColourTo(lengthDoc - 1, state);
}
Example #5
0
static char classifyWordSQL(unsigned int start,
                            unsigned int end,
                            WordList *keywordlists[],
                            Accessor &styler,
                            unsigned int actualState,
              unsigned int prevState) {
  char s[256];
  bool wordIsNumber = isdigit(styler[start]) || (styler[start] == '.');

  WordList &kwStatements          = *keywordlists[KW_MSSQL_STATEMENTS];
    WordList &kwDataTypes           = *keywordlists[KW_MSSQL_DATA_TYPES];
    WordList &kwSystemTables        = *keywordlists[KW_MSSQL_SYSTEM_TABLES];
    WordList &kwGlobalVariables     = *keywordlists[KW_MSSQL_GLOBAL_VARIABLES];
    WordList &kwFunctions           = *keywordlists[KW_MSSQL_FUNCTIONS];
    WordList &kwStoredProcedures    = *keywordlists[KW_MSSQL_STORED_PROCEDURES];
    WordList &kwOperators           = *keywordlists[KW_MSSQL_OPERATORS];

  for (unsigned int i = 0; i < end - start + 1 && i < 128; i++) {
    s[i] = static_cast<char>(tolower(styler[start + i]));
    s[i + 1] = '\0';
  }
  char chAttr = SCE_MSSQL_IDENTIFIER;

  if (actualState == SCE_MSSQL_GLOBAL_VARIABLE) {

        if (kwGlobalVariables.InList(&s[2]))
            chAttr = SCE_MSSQL_GLOBAL_VARIABLE;

  } else if (wordIsNumber) {
    chAttr = SCE_MSSQL_NUMBER;

  } else if (prevState == SCE_MSSQL_DEFAULT_PREF_DATATYPE) {
    // Look first in datatypes
        if (kwDataTypes.InList(s))
            chAttr = SCE_MSSQL_DATATYPE;
    else if (kwOperators.InList(s))
      chAttr = SCE_MSSQL_OPERATOR;
    else if (kwStatements.InList(s))
      chAttr = SCE_MSSQL_STATEMENT;
    else if (kwSystemTables.InList(s))
      chAttr = SCE_MSSQL_SYSTABLE;
    else if (kwFunctions.InList(s))
            chAttr = SCE_MSSQL_FUNCTION;
    else if (kwStoredProcedures.InList(s))
      chAttr = SCE_MSSQL_STORED_PROCEDURE;

  } else {
    if (kwOperators.InList(s))
      chAttr = SCE_MSSQL_OPERATOR;
    else if (kwStatements.InList(s))
      chAttr = SCE_MSSQL_STATEMENT;
    else if (kwSystemTables.InList(s))
      chAttr = SCE_MSSQL_SYSTABLE;
    else if (kwFunctions.InList(s))
      chAttr = SCE_MSSQL_FUNCTION;
    else if (kwStoredProcedures.InList(s))
      chAttr = SCE_MSSQL_STORED_PROCEDURE;
    else if (kwDataTypes.InList(s))
      chAttr = SCE_MSSQL_DATATYPE;
  }

  styler.ColourTo(end, chAttr);

  return chAttr;
}
Example #6
0
static void ColouriseTACLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
	Accessor &styler) {

	styler.StartAt(startPos);

	int state = initStyle;
	if (state == SCE_C_CHARACTER)	// Does not leak onto next line
		state = SCE_C_DEFAULT;
	char chPrev = ' ';
	char chNext = styler[startPos];
	unsigned int lengthDoc = startPos + length;

	bool bInClassDefinition;

	int currentLine = styler.GetLine(startPos);
	if (currentLine > 0) {
		styler.SetLineState(currentLine, styler.GetLineState(currentLine-1));
		bInClassDefinition = (styler.GetLineState(currentLine) == 1);
	} else {
		styler.SetLineState(currentLine, 0);
		bInClassDefinition = false;
	}

	bool bInAsm = (state == SCE_C_REGEX);
	if (bInAsm)
		state = SCE_C_DEFAULT;

	styler.StartSegment(startPos);
	int visibleChars = 0;
	unsigned int i;
	for (i = startPos; i < lengthDoc; i++) {
		char ch = chNext;

		chNext = styler.SafeGetCharAt(i + 1);

		if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
			// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win) or on LF alone (Unix)
			// Avoid triggering two times on Dos/Win
			// End of line
			if (state == SCE_C_CHARACTER) {
				ColourTo(styler, i, state, bInAsm);
				state = SCE_C_DEFAULT;
			}
			visibleChars = 0;
			currentLine++;
			styler.SetLineState(currentLine, (bInClassDefinition ? 1 : 0));
		}

		if (styler.IsLeadByte(ch)) {
			chNext = styler.SafeGetCharAt(i + 2);
			chPrev = ' ';
			i += 1;
			continue;
		}

		if (state == SCE_C_DEFAULT) {
			if (isTACLwordstart(ch)) {
				ColourTo(styler, i-1, state, bInAsm);
				state = SCE_C_IDENTIFIER;
			} else if (ch == '{') {
				ColourTo(styler, i-1, state, bInAsm);
				state = SCE_C_COMMENT;
			} else if (ch == '{' && chNext == '*') {
				ColourTo(styler, i-1, state, bInAsm);
				state = SCE_C_COMMENTDOC;
			} else if (ch == '=' && chNext == '=') {
				ColourTo(styler, i-1, state, bInAsm);
				state = SCE_C_COMMENTLINE;
			} else if (ch == '"') {
				ColourTo(styler, i-1, state, bInAsm);
				state = SCE_C_STRING;
			} else if (ch == '?' && visibleChars == 0) {
				ColourTo(styler, i-1, state, bInAsm);
				state = SCE_C_PREPROCESSOR;
			} else if (isTACLoperator(ch)) {
				ColourTo(styler, i-1, state, bInAsm);
				ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
			}
		} else if (state == SCE_C_IDENTIFIER) {
			if (!isTACLwordchar(ch)) {
				int lStateChange = classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);

				if(lStateChange == 1) {
					styler.SetLineState(currentLine, 1);
					bInClassDefinition = true;
				} else if(lStateChange == 2) {
					bInAsm = true;
				} else if(lStateChange == -1) {
					styler.SetLineState(currentLine, 0);
					bInClassDefinition = false;
					bInAsm = false;
				}

				if (lStateChange == 3) {
					 state = SCE_C_COMMENTLINE;
				}
				else {
					state = SCE_C_DEFAULT;
					chNext = styler.SafeGetCharAt(i + 1);
					if (ch == '{') {
						state = SCE_C_COMMENT;
					} else if (ch == '{' && chNext == '*') {
						ColourTo(styler, i-1, state, bInAsm);
						state = SCE_C_COMMENTDOC;
					} else if (ch == '=' && chNext == '=') {
						state = SCE_C_COMMENTLINE;
					} else if (ch == '"') {
						state = SCE_C_STRING;
					} else if (isTACLoperator(ch)) {
						ColourTo(styler, i, SCE_C_OPERATOR, bInAsm);
					}
				}
			}
		} else {
			if (state == SCE_C_PREPROCESSOR) {
				if ((ch == '\r' || ch == '\n') && !(chPrev == '\\' || chPrev == '\r')) {
					ColourTo(styler, i-1, state, bInAsm);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_COMMENT) {
				if (ch == '}' || (ch == '\r' || ch == '\n') ) {
					ColourTo(styler, i, state, bInAsm);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_COMMENTDOC) {
				if (ch == '}' || (ch == '\r' || ch == '\n')) {
					if (((i > styler.GetStartSegment() + 2) || (
						(initStyle == SCE_C_COMMENTDOC) &&
						(styler.GetStartSegment() == static_cast<unsigned int>(startPos))))) {
							ColourTo(styler, i, state, bInAsm);
							state = SCE_C_DEFAULT;
					}
				}
			} else if (state == SCE_C_COMMENTLINE) {
				if (ch == '\r' || ch == '\n') {
					ColourTo(styler, i-1, state, bInAsm);
					state = SCE_C_DEFAULT;
				}
			} else if (state == SCE_C_STRING) {
				if (ch == '"' || ch == '\r' || ch == '\n') {
					ColourTo(styler, i, state, bInAsm);
					state = SCE_C_DEFAULT;
				}
			}
		}
        if (!isspacechar(ch))
            visibleChars++;
		chPrev = ch;
	}

	// Process to end of document
	if (state == SCE_C_IDENTIFIER) {
		classifyWordTACL(styler.GetStartSegment(), i - 1, keywordlists, styler, bInAsm);
		}
	else
		ColourTo(styler, lengthDoc - 1, state, bInAsm);
}
Example #7
0
static void ColourTo(Accessor &styler, unsigned int end, unsigned int attr, bool bInAsm) {
	if ((bInAsm) && (attr == SCE_C_OPERATOR || attr == SCE_C_NUMBER || attr == SCE_C_DEFAULT || attr == SCE_C_WORD || attr == SCE_C_IDENTIFIER)) {
		styler.ColourTo(end, SCE_C_REGEX);
	} else
		styler.ColourTo(end, attr);
}
Example #8
0
static void ColouriseEclDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
                            Accessor &styler) {
	WordList &keywords0 = *keywordlists[0];
	WordList &keywords1 = *keywordlists[1];
	WordList &keywords2 = *keywordlists[2];
	WordList &keywords3 = *keywordlists[3]; //Value Types
	WordList &keywords4 = *keywordlists[4];
	WordList &keywords5 = *keywordlists[5];
	WordList &keywords6 = *keywordlists[6];	//Javadoc Tags
	WordList cplusplus;
	cplusplus.Set("beginc endc");

	bool stylingWithinPreprocessor = false;

	CharacterSet setOKBeforeRE(CharacterSet::setNone, "(=,");
	CharacterSet setDoxygen(CharacterSet::setLower, "$@\\&<>#{}[]");
	CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
	CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
	CharacterSet setQualified(CharacterSet::setNone, "uUxX");

	int chPrevNonWhite = ' ';
	int visibleChars = 0;
	bool lastWordWasUUID = false;
	int styleBeforeDCKeyword = SCE_ECL_DEFAULT;
	bool continuationLine = false;

	if (initStyle == SCE_ECL_PREPROCESSOR) {
		// Set continuationLine if last character of previous line is '\'
		int lineCurrent = styler.GetLine(startPos);
		if (lineCurrent > 0) {
			int chBack = styler.SafeGetCharAt(startPos-1, 0);
			int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
			int lineEndChar = '!';
			if (chBack2 == '\r' && chBack == '\n') {
				lineEndChar = styler.SafeGetCharAt(startPos-3, 0);
			} else if (chBack == '\n' || chBack == '\r') {
				lineEndChar = chBack2;
			}
			continuationLine = lineEndChar == '\\';
		}
	}

	// look back to set chPrevNonWhite properly for better regex colouring
	if (startPos > 0) {
		int back = startPos;
		while (--back && IsSpaceEquiv(styler.StyleAt(back)))
			;
		if (styler.StyleAt(back) == SCE_ECL_OPERATOR) {
			chPrevNonWhite = styler.SafeGetCharAt(back);
		}
	}

	StyleContext sc(startPos, length, initStyle, styler);

	for (; sc.More(); sc.Forward()) {
		if (sc.atLineStart) {
			if (sc.state == SCE_ECL_STRING) {
				// Prevent SCE_ECL_STRINGEOL from leaking back to previous line which
				// ends with a line continuation by locking in the state upto this position.
				sc.SetState(SCE_ECL_STRING);
			}
			// Reset states to begining of colourise so no surprises
			// if different sets of lines lexed.
			visibleChars = 0;
			lastWordWasUUID = false;
		}

		// Handle line continuation generically.
		if (sc.ch == '\\') {
			if (sc.chNext == '\n' || sc.chNext == '\r') {
				sc.Forward();
				if (sc.ch == '\r' && sc.chNext == '\n') {
					sc.Forward();
				}
				continuationLine = true;
				continue;
			}
		}

		// Determine if the current state should terminate.
		switch (sc.state) {
			case SCE_ECL_ADDED:
			case SCE_ECL_DELETED:
			case SCE_ECL_CHANGED:
			case SCE_ECL_MOVED:
			if (sc.atLineStart)
					sc.SetState(SCE_ECL_DEFAULT);
				break;
			case SCE_ECL_OPERATOR:
				sc.SetState(SCE_ECL_DEFAULT);
				break;
			case SCE_ECL_NUMBER:
				// We accept almost anything because of hex. and number suffixes
				if (!setWord.Contains(sc.ch)) {
					sc.SetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_IDENTIFIER:
				if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
					char s[1000];
					sc.GetCurrentLowered(s, sizeof(s));
					if (keywords0.InList(s)) {
						lastWordWasUUID = strcmp(s, "uuid") == 0;
						sc.ChangeState(SCE_ECL_WORD0);
					} else if (keywords1.InList(s)) {
						sc.ChangeState(SCE_ECL_WORD1);
					} else if (keywords2.InList(s)) {
						sc.ChangeState(SCE_ECL_WORD2);
					} else if (keywords4.InList(s)) {
						sc.ChangeState(SCE_ECL_WORD4);
					} else if (keywords5.InList(s)) {
						sc.ChangeState(SCE_ECL_WORD5);
					}
					else	//Data types are of from KEYWORD## 
					{
						int i = static_cast<int>(strlen(s)) - 1;
						while(i >= 0 && (isdigit(s[i]) || s[i] == '_'))
							--i;

						char s2[1000];
						strncpy(s2, s, i + 1);
						s2[i + 1] = 0;
						if (keywords3.InList(s2)) {
							sc.ChangeState(SCE_ECL_WORD3);
						} 
					}
					sc.SetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_PREPROCESSOR:
				if (sc.atLineStart && !continuationLine) {
					sc.SetState(SCE_ECL_DEFAULT);
				} else if (stylingWithinPreprocessor) {
					if (IsASpace(sc.ch)) {
						sc.SetState(SCE_ECL_DEFAULT);
					}
				} else {
					if (sc.Match('/', '*') || sc.Match('/', '/')) {
						sc.SetState(SCE_ECL_DEFAULT);
					}
				}
				break;
			case SCE_ECL_COMMENT:
				if (sc.Match('*', '/')) {
					sc.Forward();
					sc.ForwardSetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_COMMENTDOC:
				if (sc.Match('*', '/')) {
					sc.Forward();
					sc.ForwardSetState(SCE_ECL_DEFAULT);
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
					// Verify that we have the conditions to mark a comment-doc-keyword
					if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
						styleBeforeDCKeyword = SCE_ECL_COMMENTDOC;
						sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
					}
				}
				break;
			case SCE_ECL_COMMENTLINE:
				if (sc.atLineStart) {
					sc.SetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_COMMENTLINEDOC:
				if (sc.atLineStart) {
					sc.SetState(SCE_ECL_DEFAULT);
				} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
					// Verify that we have the conditions to mark a comment-doc-keyword
					if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
						styleBeforeDCKeyword = SCE_ECL_COMMENTLINEDOC;
						sc.SetState(SCE_ECL_COMMENTDOCKEYWORD);
					}
				}
				break;
			case SCE_ECL_COMMENTDOCKEYWORD:
				if ((styleBeforeDCKeyword == SCE_ECL_COMMENTDOC) && sc.Match('*', '/')) {
					sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
					sc.Forward();
					sc.ForwardSetState(SCE_ECL_DEFAULT);
				} else if (!setDoxygen.Contains(sc.ch)) {
					char s[1000];
					sc.GetCurrentLowered(s, sizeof(s));
					if (!IsASpace(sc.ch) || !keywords6.InList(s+1)) {
						sc.ChangeState(SCE_ECL_COMMENTDOCKEYWORDERROR);
					}
					sc.SetState(styleBeforeDCKeyword);
				}
				break;
			case SCE_ECL_STRING:
				if (sc.atLineEnd) {
					sc.ChangeState(SCE_ECL_STRINGEOL);
				} else if (sc.ch == '\\') {
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
						sc.Forward();
					}
				} else if (sc.ch == '\"') {
					sc.ForwardSetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_CHARACTER:
				if (sc.atLineEnd) {
					sc.ChangeState(SCE_ECL_STRINGEOL);
				} else if (sc.ch == '\\') {
					if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
						sc.Forward();
					}
				} else if (sc.ch == '\'') {
					sc.ForwardSetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_REGEX:
				if (sc.atLineStart) {
					sc.SetState(SCE_ECL_DEFAULT);
				} else if (sc.ch == '/') {
					sc.Forward();
					while ((sc.ch < 0x80) && islower(sc.ch))
						sc.Forward();    // gobble regex flags
					sc.SetState(SCE_ECL_DEFAULT);
				} else if (sc.ch == '\\') {
					// Gobble up the quoted character
					if (sc.chNext == '\\' || sc.chNext == '/') {
						sc.Forward();
					}
				}
				break;
			case SCE_ECL_STRINGEOL:
				if (sc.atLineStart) {
					sc.SetState(SCE_ECL_DEFAULT);
				}
				break;
			case SCE_ECL_VERBATIM:
				if (sc.ch == '\"') {
					if (sc.chNext == '\"') {
						sc.Forward();
					} else {
						sc.ForwardSetState(SCE_ECL_DEFAULT);
					}
				}
				break;
			case SCE_ECL_UUID:
				if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
					sc.SetState(SCE_ECL_DEFAULT);
				}
				break;
		}

		// Determine if a new state should be entered.
		int lineCurrent = styler.GetLine(sc.currentPos);
		int lineState = styler.GetLineState(lineCurrent);
		if (sc.state == SCE_ECL_DEFAULT) {
			if (lineState) {
				sc.SetState(lineState);
			}
			else if (sc.Match('@', '\"')) {
				sc.SetState(SCE_ECL_VERBATIM);
				sc.Forward();
			} else if (setQualified.Contains(sc.ch) && sc.chNext == '\'') {
				sc.SetState(SCE_ECL_CHARACTER);
				sc.Forward();
			} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				if (lastWordWasUUID) {
					sc.SetState(SCE_ECL_UUID);
					lastWordWasUUID = false;
				} else {
					sc.SetState(SCE_ECL_NUMBER);
				}
			} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
				if (lastWordWasUUID) {
					sc.SetState(SCE_ECL_UUID);
					lastWordWasUUID = false;
				} else {
					sc.SetState(SCE_ECL_IDENTIFIER);
				}
			} else if (sc.Match('/', '*')) {
				if (sc.Match("/**") || sc.Match("/*!")) {	// Support of Qt/Doxygen doc. style
					sc.SetState(SCE_ECL_COMMENTDOC);
				} else {
					sc.SetState(SCE_ECL_COMMENT);
				}
				sc.Forward();	// Eat the * so it isn't used for the end of the comment
			} else if (sc.Match('/', '/')) {
				if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
					// Support of Qt/Doxygen doc. style
					sc.SetState(SCE_ECL_COMMENTLINEDOC);
				else
					sc.SetState(SCE_ECL_COMMENTLINE);
			} else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite)) {
				sc.SetState(SCE_ECL_REGEX);	// JavaScript's RegEx
//			} else if (sc.ch == '\"') {
//				sc.SetState(SCE_ECL_STRING);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_ECL_CHARACTER);
			} else if (sc.ch == '#' && visibleChars == 0) {
				// Preprocessor commands are alone on their line
				sc.SetState(SCE_ECL_PREPROCESSOR);
				// Skip whitespace between # and preprocessor word
				do {
					sc.Forward();
				} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
				if (sc.atLineEnd) {
					sc.SetState(SCE_ECL_DEFAULT);
				}
			} else if (isoperator(static_cast<char>(sc.ch))) {
				sc.SetState(SCE_ECL_OPERATOR);
			}
		}

		if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
			chPrevNonWhite = sc.ch;
			visibleChars++;
		}
		continuationLine = false;
	}
	sc.Complete();

}
Example #9
0
static void ColouriseKixDoc(unsigned int startPos, int length, int initStyle,
                           WordList *keywordlists[], Accessor &styler) {

  WordList &keywords = *keywordlists[0];
  WordList &keywords2 = *keywordlists[1];
  WordList &keywords3 = *keywordlists[2];
//	WordList &keywords4 = *keywordlists[3];

  styler.StartAt(startPos);

  StyleContext sc(startPos, length, initStyle, styler);

  for (; sc.More(); sc.Forward()) {

    if (sc.state == SCE_KIX_COMMENT) {
      if (sc.atLineEnd) {
        sc.SetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_STRING1) {
      // This is a doubles quotes string
      if (sc.ch == '\"') {
        sc.ForwardSetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_STRING2) {
      // This is a single quote string
      if (sc.ch == '\'') {
        sc.ForwardSetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_NUMBER) {
      if (!IsADigit(sc.ch)) {
        sc.SetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_VAR) {
      if (!IsAWordChar(sc.ch)) {
        sc.SetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_MACRO) {
      if (!IsAWordChar(sc.ch) && !IsADigit(sc.ch)) {
        char s[100];
        sc.GetCurrentLowered(s, sizeof(s));

        if (!keywords3.InList(&s[1])) {
          sc.ChangeState(SCE_KIX_DEFAULT);
        }
        sc.SetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_OPERATOR) {
      if (!IsOperator(sc.ch)) {
        sc.SetState(SCE_KIX_DEFAULT);
      }
    } else if (sc.state == SCE_KIX_IDENTIFIER) {
      if (!IsAWordChar(sc.ch)) {
        char s[100];
        sc.GetCurrentLowered(s, sizeof(s));

        if (keywords.InList(s)) {
          sc.ChangeState(SCE_KIX_KEYWORD);
        } else if (keywords2.InList(s)) {
          sc.ChangeState(SCE_KIX_FUNCTIONS);
        }
        sc.SetState(SCE_KIX_DEFAULT);
      }
    }

    // Determine if a new state should be entered.
    if (sc.state == SCE_KIX_DEFAULT) {
      if (sc.ch == ';') {
        sc.SetState(SCE_KIX_COMMENT);
      } else if (sc.ch == '\"') {
        sc.SetState(SCE_KIX_STRING1);
      } else if (sc.ch == '\'') {
        sc.SetState(SCE_KIX_STRING2);
      } else if (sc.ch == '$') {
        sc.SetState(SCE_KIX_VAR);
      } else if (sc.ch == '@') {
        sc.SetState(SCE_KIX_MACRO);
      } else if (IsADigit(sc.ch) || ((sc.ch == '.' || sc.ch == '&') && IsADigit(sc.chNext))) {
        sc.SetState(SCE_KIX_NUMBER);
      } else if (IsOperator(sc.ch)) {
        sc.SetState(SCE_KIX_OPERATOR);
      } else if (IsAWordChar(sc.ch)) {
        sc.SetState(SCE_KIX_IDENTIFIER);
      }
    }
  }
  sc.Complete();
}
Example #10
0
static void FoldAU3Doc(Sci_PositionU startPos, Sci_Position length, int, WordList *[], Accessor &styler)
{
	Sci_Position endPos = startPos + length;
	// 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 = styler.GetPropertyInt("fold.compact", 1) != 0;
	bool foldpreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
	// Backtrack to previous line in case need to fix its fold status
	Sci_Position lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		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 FirstWordStart = false;
	bool FirstWordEnd = false;
	char szKeyword[11]="";
	int	 szKeywordlen = 0;
	char szThen[5]="";
	int	 szThenlen = 0;
	bool ThenFoundLast = false;
	// var for indentlevel
	int levelCurrent = SC_FOLDLEVELBASE;
	if (lineCurrent > 0)
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
	int levelNext = levelCurrent;
	//
	int	visibleChars = 0;
	char chNext = styler.SafeGetCharAt(startPos);
	char chPrev = ' ';
	//
	for (Sci_Position i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		if (IsAWordChar(ch)) {
			visibleChars++;
		}
		// get the syle for the current character neede to check in comment
		int stylech = styler.StyleAt(i);
		// get first word for the line for indent check max 9 characters
		if (FirstWordStart && (!(FirstWordEnd))) {
			if (!IsAWordChar(ch)) {
				FirstWordEnd = true;
				szKeyword[szKeywordlen] = '\0';
			}
			else {
				if (szKeywordlen < 10) {
				szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
				}
			}
		}
		// start the capture of the first word
		if (!(FirstWordStart)) {
			if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
				FirstWordStart = true;
				szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
			}
		}
		// only process this logic when not in comment section
		if (!(stylech == SCE_AU3_COMMENT)) {
			if (ThenFoundLast) {
				if (IsAWordChar(ch)) {
					ThenFoundLast = false;
				}
			}
			// find out if the word "then" is the last on a "if" line
			if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
				if (szThenlen == 4) {
					szThen[0] = szThen[1];
					szThen[1] = szThen[2];
					szThen[2] = szThen[3];
					szThen[3] = static_cast<char>(tolower(ch));
					if (strcmp(szThen,"then") == 0 ) {
						ThenFoundLast = true;
					}
				}
				else {
					szThen[szThenlen++] = static_cast<char>(tolower(ch));
					if (szThenlen == 5) {
						szThen[4] = '\0';
					}
				}
			}
		}
		// End of Line found so process the information
		if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
			// **************************
			// 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 (szKeywordlen > 0 && (!(chPrev == '_')) &&
				((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
				szKeyword[szKeywordlen] = '\0';
				// only fold "if" last keyword is "then"  (else its a one line if)
				if (strcmp(szKeyword,"if") == 0  && ThenFoundLast) {
						levelNext++;
				}
				// create new fold for these words
				if (strcmp(szKeyword,"do") == 0   || strcmp(szKeyword,"for") == 0 ||
					strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
					strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
						levelNext++;
				}
				// create double Fold for select&switch because Case will subtract one of the current level
				if (strcmp(szKeyword,"select") == 0 || strcmp(szKeyword,"switch") == 0) {
						levelNext++;
						levelNext++;
				}
				// end the fold for these words before the current line
				if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
					strcmp(szKeyword,"next") == 0    || strcmp(szKeyword,"until") == 0 ||
					strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
						levelNext--;
						levelCurrent--;
				}
				// end the fold for these words before the current line and Start new fold
				if (strcmp(szKeyword,"case") == 0      || strcmp(szKeyword,"else") == 0 ||
					strcmp(szKeyword,"elseif") == 0 ) {
						levelCurrent--;
				}
				// end the double fold for this word before the current line
				if (strcmp(szKeyword,"endselect") == 0 || strcmp(szKeyword,"endswitch") == 0 ) {
						levelNext--;
						levelNext--;
						levelCurrent--;
						levelCurrent--;
				}
				// end the fold for these words on the current line
				if (strcmp(szKeyword,"#endregion") == 0 ) {
						levelNext--;
				}
			}
			// Preprocessor and Comment folding
			int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
			// *************************************
			// Folding logic for preprocessor blocks
			// *************************************
			// process preprosessor line
			if (foldpreprocessor && style == SCE_AU3_PREPROCESSOR) {
				if (!(stylePrev == SCE_AU3_PREPROCESSOR) && (styleNext == SCE_AU3_PREPROCESSOR)) {
				    levelNext++;
				}
				// fold till the last line for normal comment lines
				else if (stylePrev == SCE_AU3_PREPROCESSOR && !(styleNext == SCE_AU3_PREPROCESSOR)) {
					levelNext--;
				}
			}
			// *********************************
			// 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_AU3_COMMENT)
						&& stylePrev == SCE_AU3_COMMENT
						&& style == SCE_AU3_COMMENT) {
					levelNext--;
				}
				// fold till the one but last line for Blockcomment lines
				else if (IsStreamCommentStyle(stylePrev)
						&& !(styleNext == SCE_AU3_COMMENTBLOCK)
						&& style == SCE_AU3_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 character is an Underscore then don't reset since the line continues on the next line.
			if (!(chPrev == '_')) {
				szKeywordlen = 0;
				szThenlen = 0;
				FirstWordStart = false;
				FirstWordEnd = false;
				ThenFoundLast = false;
			}
		}
		// save the last processed character
		if (!isspacechar(ch)) {
			chPrev = ch;
			visibleChars++;
		}
	}
}
Example #11
0
// 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
// and to make it possible to fiddle the current level for "} else {".
static void FoldEclDoc(unsigned int startPos, int length, int initStyle, 
					   WordList *[], Accessor &styler) {
	bool foldComment = true;
	bool foldPreprocessor = true;
	bool foldCompact = true;
	bool foldAtElse = true;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelCurrent = SC_FOLDLEVELBASE;
	if (lineCurrent > 0)
		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
	int levelMinCurrent = levelCurrent;
	int levelNext = levelCurrent;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;
	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		if (foldComment && IsStreamCommentStyle(style)) {
			if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_ECL_COMMENTLINEDOC)) {
				levelNext++;
			} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_ECL_COMMENTLINEDOC) && !atEOL) {
				// Comments don't end at end of line and the next character may be unstyled.
				levelNext--;
			}
		}
		if (foldComment && (style == SCE_ECL_COMMENTLINE)) {
			if ((ch == '/') && (chNext == '/')) {
				char chNext2 = styler.SafeGetCharAt(i + 2);
				if (chNext2 == '{') {
					levelNext++;
				} else if (chNext2 == '}') {
					levelNext--;
				}
			}
		}
		if (foldPreprocessor && (style == SCE_ECL_PREPROCESSOR)) {
			if (ch == '#') {
				unsigned int j = i + 1;
				while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
					j++;
				}
				if (MatchNoCase(styler, j, "region") || MatchNoCase(styler, j, "if")) {
					levelNext++;
				} else if (MatchNoCase(styler, j, "endregion") || MatchNoCase(styler, j, "end")) {
					levelNext--;
				}
			}
		}
		if (style == SCE_ECL_OPERATOR) {
			if (ch == '{') {
				// Measure the minimum before a '{' to allow
				// folding on "} else {"
				if (levelMinCurrent > levelNext) {
					levelMinCurrent = levelNext;
				}
				levelNext++;
			} else if (ch == '}') {
				levelNext--;
			}
		}
		if (style == SCE_ECL_WORD2) {
			if (MatchNoCase(styler, i, "record") || MatchNoCase(styler, i, "transform") || MatchNoCase(styler, i, "type") || MatchNoCase(styler, i, "function") || 
				MatchNoCase(styler, i, "module") || MatchNoCase(styler, i, "service") || MatchNoCase(styler, i, "interface") || MatchNoCase(styler, i, "ifblock") ||
				MatchNoCase(styler, i, "macro") || MatchNoCase(styler, i, "beginc++")) {
				levelNext++;
			} else if (MatchNoCase(styler, i, "endmacro") || MatchNoCase(styler, i, "endc++") || MatchNoCase(styler, i, "end")) {
				levelNext--;
			}
		}
		if (atEOL || (i == endPos-1)) {
			int levelUse = levelCurrent;
			if (foldAtElse) {
				levelUse = levelMinCurrent;
			}
			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;
			levelMinCurrent = levelCurrent;
			if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
				// There is an empty line at end of file so give it same level and empty
				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
			}
			visibleChars = 0;
		}
		if (!IsASpace(ch))
			visibleChars++;
	}
}
Example #12
0
//
// syntax highlighting logic
static void ColouriseAU3Doc(Sci_PositionU startPos,
							Sci_Position length, int initStyle,
							WordList *keywordlists[],
							Accessor &styler) {

    WordList &keywords = *keywordlists[0];
    WordList &keywords2 = *keywordlists[1];
    WordList &keywords3 = *keywordlists[2];
    WordList &keywords4 = *keywordlists[3];
    WordList &keywords5 = *keywordlists[4];
    WordList &keywords6 = *keywordlists[5];
    WordList &keywords7 = *keywordlists[6];
    WordList &keywords8 = *keywordlists[7];
	// find the first previous line without continuation character at the end
	Sci_Position lineCurrent = styler.GetLine(startPos);
	Sci_Position s_startPos = startPos;
	// When not inside a Block comment: find First line without _
	if (!(initStyle==SCE_AU3_COMMENTBLOCK)) {
		while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
			   (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
			lineCurrent--;
			startPos = styler.LineStart(lineCurrent); // get start position
			initStyle =  0;                           // reset the start style to 0
		}
	}
	// Set the new length to include it from the start and set the start position
	length = length + s_startPos - startPos;      // correct the total length to process
    styler.StartAt(startPos);

    StyleContext sc(startPos, length, initStyle, styler);
	char si;     // string indicator "=1 '=2
	char ni;     // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
	char ci;     // comment indicator 0=not linecomment(;)
	char s_save[100] = "";
	si=0;
	ni=0;
	ci=0;
	//$$$
    for (; sc.More(); sc.Forward()) {
		char s[100];
		sc.GetCurrentLowered(s, sizeof(s));
		// **********************************************
		// save the total current word for eof processing
		if (IsAWordChar(sc.ch) || 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';
			}
		}
		// **********************************************
		//
		switch (sc.state)
        {
            case SCE_AU3_COMMENTBLOCK:
            {
				//Reset at line end
				if (sc.atLineEnd) {
					ci=0;
					if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
						if (sc.atLineEnd)
							sc.SetState(SCE_AU3_DEFAULT);
						else
							sc.SetState(SCE_AU3_COMMENTBLOCK);
					}
					break;
				}
				//skip rest of line when a ; is encountered
				if (sc.chPrev == ';') {
					ci=2;
					sc.SetState(SCE_AU3_COMMENTBLOCK);
				}
				// skip rest of the line
				if (ci==2)
					break;
				// check when first character is detected on the line
				if (ci==0) {
					if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
						ci=1;
						sc.SetState(SCE_AU3_COMMENTBLOCK);
					}
					break;
				}
				if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && strcmp(s, "#comments") == 0))) {
					if ((strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0))
							sc.SetState(SCE_AU3_COMMENT);  // set to comment line for the rest of the line
					else
						ci=2;  // line doesn't begin with #CE so skip the rest of the line
				}
				break;
			}
            case SCE_AU3_COMMENT:
            {
                if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_OPERATOR:
            {
                // check if its a COMobject
				if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
					sc.SetState(SCE_AU3_COMOBJ);
				}
				else {
					sc.SetState(SCE_AU3_DEFAULT);
				}
                break;
            }
            case SCE_AU3_SPECIAL:
            {
                if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
				if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
            case SCE_AU3_KEYWORD:
            {
                if (!(IsAWordChar(sc.ch) || (sc.ch == '-' && (strcmp(s, "#comments") == 0 || strcmp(s, "#include") == 0))))
                {
                    if (!IsTypeCharacter(sc.ch))
                    {
						if (strcmp(s, "#cs")== 0 || strcmp(s, "#comments-start")== 0 )
						{
							sc.ChangeState(SCE_AU3_COMMENTBLOCK);
							sc.SetState(SCE_AU3_COMMENTBLOCK);
							break;
						}
						else if (keywords.InList(s)) {
							sc.ChangeState(SCE_AU3_KEYWORD);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (keywords2.InList(s)) {
							sc.ChangeState(SCE_AU3_FUNCTION);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (keywords3.InList(s)) {
							sc.ChangeState(SCE_AU3_MACRO);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (keywords5.InList(s)) {
							sc.ChangeState(SCE_AU3_PREPROCESSOR);
							sc.SetState(SCE_AU3_DEFAULT);
							if (strcmp(s, "#include")== 0)
							{
								si = 3;   // use to determine string start for #inlude <>
							}
						}
						else if (keywords6.InList(s)) {
							sc.ChangeState(SCE_AU3_SPECIAL);
							sc.SetState(SCE_AU3_SPECIAL);
						}
						else if ((keywords7.InList(s)) && (!IsAOperator(static_cast<char>(sc.ch)))) {
							sc.ChangeState(SCE_AU3_EXPAND);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (keywords8.InList(s)) {
							sc.ChangeState(SCE_AU3_UDF);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (strcmp(s, "_") == 0) {
							sc.ChangeState(SCE_AU3_OPERATOR);
							sc.SetState(SCE_AU3_DEFAULT);
						}
						else if (!IsAWordChar(sc.ch)) {
							sc.ChangeState(SCE_AU3_DEFAULT);
							sc.SetState(SCE_AU3_DEFAULT);
						}
					}
				}
                if (sc.atLineEnd) {
					sc.SetState(SCE_AU3_DEFAULT);}
                break;
            }
			case SCE_AU3_NUMBER:
            {
				// Numeric indicator error=9 normal=0 normal+dec=1 hex=2 E-not=3
				//
				// test for Hex notation
				if (strcmp(s, "0") == 0 && (sc.ch == 'x' || sc.ch == 'X') && ni == 0)
				{
					ni = 2;
					break;
				}
				// test for E notation
				if (IsADigit(sc.chPrev) && (sc.ch == 'e' || sc.ch == 'E') && ni <= 1)
				{
					ni = 3;
					break;
				}
				//  Allow Hex characters inside hex numeric strings
				if ((ni == 2) &&
					(sc.ch == 'a' || sc.ch == 'b' || sc.ch == 'c' || sc.ch == 'd' || sc.ch == 'e' || sc.ch == 'f' ||
					 sc.ch == 'A' || sc.ch == 'B' || sc.ch == 'C' || sc.ch == 'D' || sc.ch == 'E' || sc.ch == 'F' ))
				{
					break;
				}
				// test for 1 dec point only
				if (sc.ch == '.')
				{
					if (ni==0)
					{
						ni=1;
					}
					else
					{
						ni=9;
					}
					break;
				}
				// end of numeric string ?
				if (!(IsADigit(sc.ch)))
				{
					if (ni==9)
					{
						sc.ChangeState(SCE_AU3_DEFAULT);
					}
					sc.SetState(SCE_AU3_DEFAULT);
				}
				break;
			}
			case SCE_AU3_VARIABLE:
			{
				// Check if its a COMObject
				if (sc.ch == '.' && !IsADigit(sc.chNext)) {
					sc.SetState(SCE_AU3_OPERATOR);
				}
				else if (!IsAWordChar(sc.ch)) {
					sc.SetState(SCE_AU3_DEFAULT);
				}
				break;
            }
			case SCE_AU3_COMOBJ:
			{
				if (!(IsAWordChar(sc.ch))) {
					sc.SetState(SCE_AU3_DEFAULT);
				}
				break;
            }
            case SCE_AU3_STRING:
            {
				// check for " to end a double qouted string or
				// check for ' to end a single qouted string
	            if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
				{
					sc.ForwardSetState(SCE_AU3_DEFAULT);
					si=0;
					break;
				}
                if (sc.atLineEnd)
				{
					si=0;
					// at line end and not found a continuation char then reset to default
					Sci_Position lineCurrent = styler.GetLine(sc.currentPos);
					if (!IsContinuationLine(lineCurrent,styler))
					{
						sc.SetState(SCE_AU3_DEFAULT);
						break;
					}
				}
				// find Sendkeys in a STRING
				if (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ) {
					sc.SetState(SCE_AU3_SENT);}
				break;
            }

            case SCE_AU3_SENT:
            {
				// Send key string ended
				if (sc.chPrev == '}' && sc.ch != '}')
				{
					// set color to SENDKEY when valid sendkey .. else set back to regular string
					char sk[100];
					// split {111 222} and return {111} and check if 222 is valid.
					// if return code = 1 then invalid 222 so must be string
					if (GetSendKey(s,sk))
					{
						sc.ChangeState(SCE_AU3_STRING);
					}
					// if single char between {?} then its ok as sendkey for a single character
					else if (strlen(sk) == 3)
					{
						sc.ChangeState(SCE_AU3_SENT);
					}
					// if sendkey {111} is in table then ok as sendkey
					else if (keywords4.InList(sk))
					{
						sc.ChangeState(SCE_AU3_SENT);
					}
					else
					{
						sc.ChangeState(SCE_AU3_STRING);
					}
					sc.SetState(SCE_AU3_STRING);
				}
				else
				{
					// check if the start is a valid SendKey start
					Sci_Position		nPos	= 0;
					int		nState	= 1;
					char	cTemp;
					while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
					{
						if (cTemp == '{' && nState == 1)
						{
							nState = 2;
						}
						if (nState == 1 && !(cTemp == '+' || cTemp == '!' || cTemp == '^' || cTemp == '#' ))
						{
							nState = 0;
						}
						nPos++;
					}
					//Verify characters infront of { ... if not assume  regular string
					if (nState == 1 && (!(sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' ))) {
						sc.ChangeState(SCE_AU3_STRING);
						sc.SetState(SCE_AU3_STRING);
					}
					// If invalid character found then assume its a regular string
					if (nState == 0) {
						sc.ChangeState(SCE_AU3_STRING);
						sc.SetState(SCE_AU3_STRING);
					}
				}
				// check if next portion is again a sendkey
				if (sc.atLineEnd)
				{
					sc.ChangeState(SCE_AU3_STRING);
					sc.SetState(SCE_AU3_DEFAULT);
					si = 0;  // reset string indicator
				}
				//* check in next characters following a sentkey are again a sent key
				// Need this test incase of 2 sentkeys like {F1}{ENTER} but not detect {{}
				if (sc.state == SCE_AU3_STRING && (sc.ch == '{' || sc.ch == '+' || sc.ch == '!' || sc.ch == '^' || sc.ch == '#' )) {
					sc.SetState(SCE_AU3_SENT);}
				// check to see if the string ended...
				// Sendkey string isn't complete but the string ended....
				if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\''))
				{
					sc.ChangeState(SCE_AU3_STRING);
					sc.ForwardSetState(SCE_AU3_DEFAULT);
				}
				break;
            }
        }  //switch (sc.state)

        // Determine if a new state should be entered:

		if (sc.state == SCE_AU3_DEFAULT)
        {
            if (sc.ch == ';') {sc.SetState(SCE_AU3_COMMENT);}
            else if (sc.ch == '#') {sc.SetState(SCE_AU3_KEYWORD);}
            else if (sc.ch == '$') {sc.SetState(SCE_AU3_VARIABLE);}
            else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
            else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
            //else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
            else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);}  // string after #include
            else if (sc.ch == '\"') {
				sc.SetState(SCE_AU3_STRING);
				si = 1;	}
            else if (sc.ch == '\'') {
				sc.SetState(SCE_AU3_STRING);
				si = 2;	}
            else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
			{
				sc.SetState(SCE_AU3_NUMBER);
				ni = 0;
			}
            else if (IsAWordStart(sc.ch)) {sc.SetState(SCE_AU3_KEYWORD);}
            else if (IsAOperator(static_cast<char>(sc.ch))) {sc.SetState(SCE_AU3_OPERATOR);}
			else if (sc.atLineEnd) {sc.SetState(SCE_AU3_DEFAULT);}
        }
    }      //for (; sc.More(); sc.Forward())

	//*************************************
	// Colourize the last word correctly
	//*************************************
	if (sc.state == SCE_AU3_KEYWORD)
		{
		if (strcmp(s_save, "#cs")== 0 || strcmp(s_save, "#comments-start")== 0 )
		{
			sc.ChangeState(SCE_AU3_COMMENTBLOCK);
			sc.SetState(SCE_AU3_COMMENTBLOCK);
		}
		else if (keywords.InList(s_save)) {
			sc.ChangeState(SCE_AU3_KEYWORD);
			sc.SetState(SCE_AU3_KEYWORD);
		}
		else if (keywords2.InList(s_save)) {
			sc.ChangeState(SCE_AU3_FUNCTION);
			sc.SetState(SCE_AU3_FUNCTION);
		}
		else if (keywords3.InList(s_save)) {
			sc.ChangeState(SCE_AU3_MACRO);
			sc.SetState(SCE_AU3_MACRO);
		}
		else if (keywords5.InList(s_save)) {
			sc.ChangeState(SCE_AU3_PREPROCESSOR);
			sc.SetState(SCE_AU3_PREPROCESSOR);
		}
		else if (keywords6.InList(s_save)) {
			sc.ChangeState(SCE_AU3_SPECIAL);
			sc.SetState(SCE_AU3_SPECIAL);
		}
		else if (keywords7.InList(s_save) && sc.atLineEnd) {
			sc.ChangeState(SCE_AU3_EXPAND);
			sc.SetState(SCE_AU3_EXPAND);
		}
		else if (keywords8.InList(s_save)) {
			sc.ChangeState(SCE_AU3_UDF);
			sc.SetState(SCE_AU3_UDF);
		}
		else {
			sc.ChangeState(SCE_AU3_DEFAULT);
			sc.SetState(SCE_AU3_DEFAULT);
		}
	}
	if (sc.state == SCE_AU3_SENT)
    {
		// Send key string ended
		if (sc.chPrev == '}' && sc.ch != '}')
		{
			// set color to SENDKEY when valid sendkey .. else set back to regular string
			char sk[100];
			// split {111 222} and return {111} and check if 222 is valid.
			// if return code = 1 then invalid 222 so must be string
			if (GetSendKey(s_save,sk))
			{
				sc.ChangeState(SCE_AU3_STRING);
			}
			// if single char between {?} then its ok as sendkey for a single character
			else if (strlen(sk) == 3)
			{
				sc.ChangeState(SCE_AU3_SENT);
			}
			// if sendkey {111} is in table then ok as sendkey
			else if (keywords4.InList(sk))
			{
				sc.ChangeState(SCE_AU3_SENT);
			}
			else
			{
				sc.ChangeState(SCE_AU3_STRING);
			}
			sc.SetState(SCE_AU3_STRING);
		}
		// check if next portion is again a sendkey
		if (sc.atLineEnd)
		{
			sc.ChangeState(SCE_AU3_STRING);
			sc.SetState(SCE_AU3_DEFAULT);
		}
    }
	//*************************************
	sc.Complete();
}
Example #13
0
static void FoldBashDoc(Sci_PositionU startPos, Sci_Position length, int, WordList *[],
						Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	Sci_PositionU endPos = startPos + length;
	int visibleChars = 0;
	int skipHereCh = 0;
	Sci_Position lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	for (Sci_PositionU i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
		// Comment folding
		if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
		{
			if (!IsCommentLine(lineCurrent - 1, styler)
				&& IsCommentLine(lineCurrent + 1, styler))
				levelCurrent++;
			else if (IsCommentLine(lineCurrent - 1, styler)
					 && !IsCommentLine(lineCurrent + 1, styler))
				levelCurrent--;
		}
		if (style == SCE_SH_OPERATOR) {
			if (ch == '{') {
				levelCurrent++;
			} else if (ch == '}') {
				levelCurrent--;
			}
		}
		// Here Document folding
		if (style == SCE_SH_HERE_DELIM) {
			if (ch == '<' && chNext == '<') {
				if (styler.SafeGetCharAt(i + 2) == '<') {
					skipHereCh = 1;
				} else {
					if (skipHereCh == 0) {
						levelCurrent++;
					} else {
						skipHereCh = 0;
					}
				}
			}
		} else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_SH_DEFAULT) {
			levelCurrent--;
		}
		if (atEOL) {
			int lev = levelPrev;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
		}
		if (!isspacechar(ch))
			visibleChars++;
	}
	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
Example #14
0
static void ColouriseBashDoc(Sci_PositionU startPos, Sci_Position length, int initStyle,
							 WordList *keywordlists[], Accessor &styler) {

	WordList &keywords = *keywordlists[0];
	WordList cmdDelimiter, bashStruct, bashStruct_in;
	cmdDelimiter.Set("| || |& & && ; ;; ( ) { }");
	bashStruct.Set("if elif fi while until else then do done esac eval");
	bashStruct_in.Set("for case select");

	CharacterSet setWordStart(CharacterSet::setAlpha, "_");
	// note that [+-] are often parts of identifiers in shell scripts
	CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
	CharacterSet setMetaCharacter(CharacterSet::setNone, "|&;()<> \t\r\n");
	setMetaCharacter.Add(0);
	CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@");
	CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
	CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
	CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!%*,./:?@[]^`{}~");
	CharacterSet setHereDoc2(CharacterSet::setAlphaNum, "_-+!%*,./:=?@[]^`{}~");
	CharacterSet setLeftShift(CharacterSet::setDigits, "$");

	class HereDocCls {	// Class to manage HERE document elements
	public:
		int State;		// 0: '<<' encountered
		// 1: collect the delimiter
		// 2: here doc text (lines after the delimiter)
		int Quote;		// the char after '<<'
		bool Quoted;		// true if Quote in ('\'','"','`')
		bool Indent;		// indented delimiter (for <<-)
		int DelimiterLength;	// strlen(Delimiter)
		char Delimiter[HERE_DELIM_MAX];	// the Delimiter
		HereDocCls() {
			State = 0;
			Quote = 0;
			Quoted = false;
			Indent = 0;
			DelimiterLength = 0;
			Delimiter[0] = '\0';
		}
		void Append(int ch) {
			Delimiter[DelimiterLength++] = static_cast<char>(ch);
			Delimiter[DelimiterLength] = '\0';
		}
		~HereDocCls() {
		}
	};
	HereDocCls HereDoc;

	class QuoteCls {	// Class to manage quote pairs (simplified vs LexPerl)
		public:
		int Count;
		int Up, Down;
		QuoteCls() {
			Count = 0;
			Up    = '\0';
			Down  = '\0';
		}
		void Open(int u) {
			Count++;
			Up    = u;
			Down  = opposite(Up);
		}
		void Start(int u) {
			Count = 0;
			Open(u);
		}
	};
	QuoteCls Quote;

	class QuoteStackCls {	// Class to manage quote pairs that nest
		public:
		int Count;
		int Up, Down;
		int Style;
		int Depth;			// levels pushed
		int CountStack[BASH_DELIM_STACK_MAX];
		int UpStack   [BASH_DELIM_STACK_MAX];
		int StyleStack[BASH_DELIM_STACK_MAX];
		QuoteStackCls() {
			Count = 0;
			Up    = '\0';
			Down  = '\0';
			Style = 0;
			Depth = 0;
		}
		void Start(int u, int s) {
			Count = 1;
			Up    = u;
			Down  = opposite(Up);
			Style = s;
		}
		void Push(int u, int s) {
			if (Depth >= BASH_DELIM_STACK_MAX)
				return;
			CountStack[Depth] = Count;
			UpStack   [Depth] = Up;
			StyleStack[Depth] = Style;
			Depth++;
			Count = 1;
			Up    = u;
			Down  = opposite(Up);
			Style = s;
		}
		void Pop(void) {
			if (Depth <= 0)
				return;
			Depth--;
			Count = CountStack[Depth];
			Up    = UpStack   [Depth];
			Style = StyleStack[Depth];
			Down  = opposite(Up);
		}
		~QuoteStackCls() {
		}
	};
	QuoteStackCls QuoteStack;

	int numBase = 0;
	int digit;
	Sci_PositionU endPos = startPos + length;
	int cmdState = BASH_CMD_START;
	int testExprType = 0;

	// Always backtracks to the start of a line that is not a continuation
	// of the previous line (i.e. start of a bash command segment)
	Sci_Position ln = styler.GetLine(startPos);
	if (ln > 0 && startPos == static_cast<Sci_PositionU>(styler.LineStart(ln)))
		ln--;
	for (;;) {
		startPos = styler.LineStart(ln);
		if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
			break;
		ln--;
	}
	initStyle = SCE_SH_DEFAULT;

	StyleContext sc(startPos, endPos - startPos, initStyle, styler);

	for (; sc.More(); sc.Forward()) {

		// handle line continuation, updates per-line stored state
		if (sc.atLineStart) {
			ln = styler.GetLine(sc.currentPos);
			if (sc.state == SCE_SH_STRING
			 || sc.state == SCE_SH_BACKTICKS
			 || sc.state == SCE_SH_CHARACTER
			 || sc.state == SCE_SH_HERE_Q
			 || sc.state == SCE_SH_COMMENTLINE
			 || sc.state == SCE_SH_PARAM) {
				// force backtrack while retaining cmdState
				styler.SetLineState(ln, BASH_CMD_BODY);
			} else {
				if (ln > 0) {
					if ((sc.GetRelative(-3) == '\\' && sc.GetRelative(-2) == '\r' && sc.chPrev == '\n')
					 || sc.GetRelative(-2) == '\\') {	// handle '\' line continuation
						// retain last line's state
					} else
						cmdState = BASH_CMD_START;
				}
				styler.SetLineState(ln, cmdState);
			}
		}

		// controls change of cmdState at the end of a non-whitespace element
		// states BODY|TEST|ARITH persist until the end of a command segment
		// state WORD persist, but ends with 'in' or 'do' construct keywords
		int cmdStateNew = BASH_CMD_BODY;
		if (cmdState == BASH_CMD_TEST || cmdState == BASH_CMD_ARITH || cmdState == BASH_CMD_WORD)
			cmdStateNew = cmdState;
		int stylePrev = sc.state;

		// Determine if the current state should terminate.
		switch (sc.state) {
			case SCE_SH_OPERATOR:
				sc.SetState(SCE_SH_DEFAULT);
				if (cmdState == BASH_CMD_DELIM)		// if command delimiter, start new command
					cmdStateNew = BASH_CMD_START;
				else if (sc.chPrev == '\\')			// propagate command state if line continued
					cmdStateNew = cmdState;
				break;
			case SCE_SH_WORD:
				// "." never used in Bash variable names but used in file names
				if (!setWord.Contains(sc.ch)) {
					char s[500];
					char s2[10];
					sc.GetCurrent(s, sizeof(s));
					// allow keywords ending in a whitespace or command delimiter
					s2[0] = static_cast<char>(sc.ch);
					s2[1] = '\0';
					bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2);
					// 'in' or 'do' may be construct keywords
					if (cmdState == BASH_CMD_WORD) {
						if (strcmp(s, "in") == 0 && keywordEnds)
							cmdStateNew = BASH_CMD_BODY;
						else if (strcmp(s, "do") == 0 && keywordEnds)
							cmdStateNew = BASH_CMD_START;
						else
							sc.ChangeState(SCE_SH_IDENTIFIER);
						sc.SetState(SCE_SH_DEFAULT);
						break;
					}
					// a 'test' keyword starts a test expression
					if (strcmp(s, "test") == 0) {
						if (cmdState == BASH_CMD_START && keywordEnds) {
							cmdStateNew = BASH_CMD_TEST;
							testExprType = 0;
						} else
							sc.ChangeState(SCE_SH_IDENTIFIER);
					}
					// detect bash construct keywords
					else if (bashStruct.InList(s)) {
						if (cmdState == BASH_CMD_START && keywordEnds)
							cmdStateNew = BASH_CMD_START;
						else
							sc.ChangeState(SCE_SH_IDENTIFIER);
					}
					// 'for'|'case'|'select' needs 'in'|'do' to be highlighted later
					else if (bashStruct_in.InList(s)) {
						if (cmdState == BASH_CMD_START && keywordEnds)
							cmdStateNew = BASH_CMD_WORD;
						else
							sc.ChangeState(SCE_SH_IDENTIFIER);
					}
					// disambiguate option items and file test operators
					else if (s[0] == '-') {
						if (cmdState != BASH_CMD_TEST)
							sc.ChangeState(SCE_SH_IDENTIFIER);
					}
					// disambiguate keywords and identifiers
					else if (cmdState != BASH_CMD_START
						  || !(keywords.InList(s) && keywordEnds)) {
						sc.ChangeState(SCE_SH_IDENTIFIER);
					}
					sc.SetState(SCE_SH_DEFAULT);
				}
				break;
			case SCE_SH_IDENTIFIER:
				if (sc.chPrev == '\\') {	// for escaped chars
					sc.ForwardSetState(SCE_SH_DEFAULT);
				} else if (!setWord.Contains(sc.ch)) {
					sc.SetState(SCE_SH_DEFAULT);
				} else if (cmdState == BASH_CMD_ARITH && !setWordStart.Contains(sc.ch)) {
					sc.SetState(SCE_SH_DEFAULT);
				}
				break;
			case SCE_SH_NUMBER:
				digit = translateBashDigit(sc.ch);
				if (numBase == BASH_BASE_DECIMAL) {
					if (sc.ch == '#') {
						char s[10];
						sc.GetCurrent(s, sizeof(s));
						numBase = getBashNumberBase(s);
						if (numBase != BASH_BASE_ERROR)
							break;
					} else if (IsADigit(sc.ch))
						break;
				} else if (numBase == BASH_BASE_HEX) {
					if (IsADigit(sc.ch, 16))
						break;
#ifdef PEDANTIC_OCTAL
				} else if (numBase == BASH_BASE_OCTAL ||
						   numBase == BASH_BASE_OCTAL_ERROR) {
					if (digit <= 7)
						break;
					if (digit <= 9) {
						numBase = BASH_BASE_OCTAL_ERROR;
						break;
					}
#endif
				} else if (numBase == BASH_BASE_ERROR) {
					if (digit <= 9)
						break;
				} else {	// DD#DDDD number style handling
					if (digit != BASH_BASE_ERROR) {
						if (numBase <= 36) {
							// case-insensitive if base<=36
							if (digit >= 36) digit -= 26;
						}
						if (digit < numBase)
							break;
						if (digit <= 9) {
							numBase = BASH_BASE_ERROR;
							break;
						}
					}
				}
				// fallthrough when number is at an end or error
				if (numBase == BASH_BASE_ERROR
#ifdef PEDANTIC_OCTAL
					|| numBase == BASH_BASE_OCTAL_ERROR
#endif
				) {
					sc.ChangeState(SCE_SH_ERROR);
				}
				sc.SetState(SCE_SH_DEFAULT);
				break;
			case SCE_SH_COMMENTLINE:
				if (sc.atLineEnd && sc.chPrev != '\\') {
					sc.SetState(SCE_SH_DEFAULT);
				}
				break;
			case SCE_SH_HERE_DELIM:
				// From Bash info:
				// ---------------
				// Specifier format is: <<[-]WORD
				// Optional '-' is for removal of leading tabs from here-doc.
				// Whitespace acceptable after <<[-] operator
				//
				if (HereDoc.State == 0) { // '<<' encountered
					HereDoc.Quote = sc.chNext;
					HereDoc.Quoted = false;
					HereDoc.DelimiterLength = 0;
					HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
					if (sc.chNext == '\'' || sc.chNext == '\"') {	// a quoted here-doc delimiter (' or ")
						sc.Forward();
						HereDoc.Quoted = true;
						HereDoc.State = 1;
					} else if (setHereDoc.Contains(sc.chNext) ||
					           (sc.chNext == '=' && cmdState != BASH_CMD_ARITH)) {
						// an unquoted here-doc delimiter, no special handling
						HereDoc.State = 1;
					} else if (sc.chNext == '<') {	// HERE string <<<
						sc.Forward();
						sc.ForwardSetState(SCE_SH_DEFAULT);
					} else if (IsASpace(sc.chNext)) {
						// eat whitespace
					} else if (setLeftShift.Contains(sc.chNext) ||
					           (sc.chNext == '=' && cmdState == BASH_CMD_ARITH)) {
						// left shift <<$var or <<= cases
						sc.ChangeState(SCE_SH_OPERATOR);
						sc.ForwardSetState(SCE_SH_DEFAULT);
					} else {
						// symbols terminates; deprecated zero-length delimiter
						HereDoc.State = 1;
					}
				} else if (HereDoc.State == 1) { // collect the delimiter
					// * if single quoted, there's no escape
					// * if double quoted, there are \\ and \" escapes
					if ((HereDoc.Quote == '\'' && sc.ch != HereDoc.Quote) ||
					    (HereDoc.Quoted && sc.ch != HereDoc.Quote && sc.ch != '\\') ||
					    (HereDoc.Quote != '\'' && sc.chPrev == '\\') ||
					    (setHereDoc2.Contains(sc.ch))) {
						HereDoc.Append(sc.ch);
					} else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) {	// closing quote => end of delimiter
						sc.ForwardSetState(SCE_SH_DEFAULT);
					} else if (sc.ch == '\\') {
						if (HereDoc.Quoted && sc.chNext != HereDoc.Quote && sc.chNext != '\\') {
							// in quoted prefixes only \ and the quote eat the escape
							HereDoc.Append(sc.ch);
						} else {
							// skip escape prefix
						}
					} else if (!HereDoc.Quoted) {
						sc.SetState(SCE_SH_DEFAULT);
					}
					if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {	// force blowup
						sc.SetState(SCE_SH_ERROR);
						HereDoc.State = 0;
					}
				}
				break;
			case SCE_SH_HERE_Q:
				// HereDoc.State == 2
				if (sc.atLineStart) {
					sc.SetState(SCE_SH_HERE_Q);
					int prefixws = 0;
					while (sc.ch == '\t' && !sc.atLineEnd) {	// tabulation prefix
						sc.Forward();
						prefixws++;
					}
					if (prefixws > 0)
						sc.SetState(SCE_SH_HERE_Q);
					while (!sc.atLineEnd) {
						sc.Forward();
					}
					char s[HERE_DELIM_MAX];
					sc.GetCurrent(s, sizeof(s));
					if (sc.LengthCurrent() == 0) {  // '' or "" delimiters
						if ((prefixws == 0 || HereDoc.Indent) &&
							HereDoc.Quoted && HereDoc.DelimiterLength == 0)
							sc.SetState(SCE_SH_DEFAULT);
						break;
					}
					if (s[strlen(s) - 1] == '\r')
						s[strlen(s) - 1] = '\0';
					if (strcmp(HereDoc.Delimiter, s) == 0) {
						if ((prefixws == 0) ||	// indentation rule
							(prefixws > 0 && HereDoc.Indent)) {
							sc.SetState(SCE_SH_DEFAULT);
							break;
						}
					}
				}
				break;
			case SCE_SH_SCALAR:	// variable names
				if (!setParam.Contains(sc.ch)) {
					if (sc.LengthCurrent() == 1) {
						// Special variable: $(, $_ etc.
						sc.ForwardSetState(SCE_SH_DEFAULT);
					} else {
						sc.SetState(SCE_SH_DEFAULT);
					}
				}
				break;
			case SCE_SH_STRING:	// delimited styles, can nest
			case SCE_SH_BACKTICKS:
				if (sc.ch == '\\' && QuoteStack.Up != '\\') {
					if (QuoteStack.Style != BASH_DELIM_LITERAL)
						sc.Forward();
				} else if (sc.ch == QuoteStack.Down) {
					QuoteStack.Count--;
					if (QuoteStack.Count == 0) {
						if (QuoteStack.Depth > 0) {
							QuoteStack.Pop();
						} else
							sc.ForwardSetState(SCE_SH_DEFAULT);
					}
				} else if (sc.ch == QuoteStack.Up) {
					QuoteStack.Count++;
				} else {
					if (QuoteStack.Style == BASH_DELIM_STRING ||
						QuoteStack.Style == BASH_DELIM_LSTRING
					) {	// do nesting for "string", $"locale-string"
						if (sc.ch == '`') {
							QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
						} else if (sc.ch == '$' && sc.chNext == '(') {
							sc.Forward();
							QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
						}
					} else if (QuoteStack.Style == BASH_DELIM_COMMAND ||
							   QuoteStack.Style == BASH_DELIM_BACKTICK
					) {	// do nesting for $(command), `command`
						if (sc.ch == '\'') {
							QuoteStack.Push(sc.ch, BASH_DELIM_LITERAL);
						} else if (sc.ch == '\"') {
							QuoteStack.Push(sc.ch, BASH_DELIM_STRING);
						} else if (sc.ch == '`') {
							QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
						} else if (sc.ch == '$') {
							if (sc.chNext == '\'') {
								sc.Forward();
								QuoteStack.Push(sc.ch, BASH_DELIM_CSTRING);
							} else if (sc.chNext == '\"') {
								sc.Forward();
								QuoteStack.Push(sc.ch, BASH_DELIM_LSTRING);
							} else if (sc.chNext == '(') {
								sc.Forward();
								QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
							}
						}
					}
				}
				break;
			case SCE_SH_PARAM: // ${parameter}
				if (sc.ch == '\\' && Quote.Up != '\\') {
					sc.Forward();
				} else if (sc.ch == Quote.Down) {
					Quote.Count--;
					if (Quote.Count == 0) {
						sc.ForwardSetState(SCE_SH_DEFAULT);
					}
				} else if (sc.ch == Quote.Up) {
					Quote.Count++;
				}
				break;
			case SCE_SH_CHARACTER: // singly-quoted strings
				if (sc.ch == Quote.Down) {
					Quote.Count--;
					if (Quote.Count == 0) {
						sc.ForwardSetState(SCE_SH_DEFAULT);
					}
				}
				break;
		}

		// Must check end of HereDoc state 1 before default state is handled
		if (HereDoc.State == 1 && sc.atLineEnd) {
			// Begin of here-doc (the line after the here-doc delimiter):
			// Lexically, the here-doc starts from the next line after the >>, but the
			// first line of here-doc seem to follow the style of the last EOL sequence
			HereDoc.State = 2;
			if (HereDoc.Quoted) {
				if (sc.state == SCE_SH_HERE_DELIM) {
					// Missing quote at end of string! Syntax error in bash 4.3
					// Mark this bit as an error, do not colour any here-doc
					sc.ChangeState(SCE_SH_ERROR);
					sc.SetState(SCE_SH_DEFAULT);
				} else {
					// HereDoc.Quote always == '\''
					sc.SetState(SCE_SH_HERE_Q);
				}
			} else if (HereDoc.DelimiterLength == 0) {
				// no delimiter, illegal (but '' and "" are legal)
				sc.ChangeState(SCE_SH_ERROR);
				sc.SetState(SCE_SH_DEFAULT);
			} else {
				sc.SetState(SCE_SH_HERE_Q);
			}
		}

		// update cmdState about the current command segment
		if (stylePrev != SCE_SH_DEFAULT && sc.state == SCE_SH_DEFAULT) {
			cmdState = cmdStateNew;
		}
		// Determine if a new state should be entered.
		if (sc.state == SCE_SH_DEFAULT) {
			if (sc.ch == '\\') {
				// Bash can escape any non-newline as a literal
				sc.SetState(SCE_SH_IDENTIFIER);
				if (sc.chNext == '\r' || sc.chNext == '\n')
					sc.SetState(SCE_SH_OPERATOR);
			} else if (IsADigit(sc.ch)) {
				sc.SetState(SCE_SH_NUMBER);
				numBase = BASH_BASE_DECIMAL;
				if (sc.ch == '0') {	// hex,octal
					if (sc.chNext == 'x' || sc.chNext == 'X') {
						numBase = BASH_BASE_HEX;
						sc.Forward();
					} else if (IsADigit(sc.chNext)) {
#ifdef PEDANTIC_OCTAL
						numBase = BASH_BASE_OCTAL;
#else
						numBase = BASH_BASE_HEX;
#endif
					}
				}
			} else if (setWordStart.Contains(sc.ch)) {
				sc.SetState(SCE_SH_WORD);
			} else if (sc.ch == '#') {
				if (stylePrev != SCE_SH_WORD && stylePrev != SCE_SH_IDENTIFIER &&
					(sc.currentPos == 0 || setMetaCharacter.Contains(sc.chPrev))) {
					sc.SetState(SCE_SH_COMMENTLINE);
				} else {
					sc.SetState(SCE_SH_WORD);
				}
				// handle some zsh features within arithmetic expressions only
				if (cmdState == BASH_CMD_ARITH) {
					if (sc.chPrev == '[') {	// [#8] [##8] output digit setting
						sc.SetState(SCE_SH_WORD);
						if (sc.chNext == '#') {
							sc.Forward();
						}
					} else if (sc.Match("##^") && IsUpperCase(sc.GetRelative(3))) {	// ##^A
						sc.SetState(SCE_SH_IDENTIFIER);
						sc.Forward(3);
					} else if (sc.chNext == '#' && !IsASpace(sc.GetRelative(2))) {	// ##a
						sc.SetState(SCE_SH_IDENTIFIER);
						sc.Forward(2);
					} else if (setWordStart.Contains(sc.chNext)) {	// #name
						sc.SetState(SCE_SH_IDENTIFIER);
					}
				}
			} else if (sc.ch == '\"') {
				sc.SetState(SCE_SH_STRING);
				QuoteStack.Start(sc.ch, BASH_DELIM_STRING);
			} else if (sc.ch == '\'') {
				sc.SetState(SCE_SH_CHARACTER);
				Quote.Start(sc.ch);
			} else if (sc.ch == '`') {
				sc.SetState(SCE_SH_BACKTICKS);
				QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
			} else if (sc.ch == '$') {
				if (sc.Match("$((")) {
					sc.SetState(SCE_SH_OPERATOR);	// handle '((' later
					continue;
				}
				sc.SetState(SCE_SH_SCALAR);
				sc.Forward();
				if (sc.ch == '{') {
					sc.ChangeState(SCE_SH_PARAM);
					Quote.Start(sc.ch);
				} else if (sc.ch == '\'') {
					sc.ChangeState(SCE_SH_STRING);
					QuoteStack.Start(sc.ch, BASH_DELIM_CSTRING);
				} else if (sc.ch == '"') {
					sc.ChangeState(SCE_SH_STRING);
					QuoteStack.Start(sc.ch, BASH_DELIM_LSTRING);
				} else if (sc.ch == '(') {
					sc.ChangeState(SCE_SH_BACKTICKS);
					QuoteStack.Start(sc.ch, BASH_DELIM_COMMAND);
				} else if (sc.ch == '`') {	// $` seen in a configure script, valid?
					sc.ChangeState(SCE_SH_BACKTICKS);
					QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
				} else {
					continue;	// scalar has no delimiter pair
				}
			} else if (sc.Match('<', '<')) {
				sc.SetState(SCE_SH_HERE_DELIM);
				HereDoc.State = 0;
				if (sc.GetRelative(2) == '-') {	// <<- indent case
					HereDoc.Indent = true;
					sc.Forward();
				} else {
					HereDoc.Indent = false;
				}
			} else if (sc.ch == '-'	&&	// one-char file test operators
					   setSingleCharOp.Contains(sc.chNext) &&
					   !setWord.Contains(sc.GetRelative(2)) &&
					   IsASpace(sc.chPrev)) {
				sc.SetState(SCE_SH_WORD);
				sc.Forward();
			} else if (setBashOperator.Contains(sc.ch)) {
				char s[10];
				bool isCmdDelim = false;
				sc.SetState(SCE_SH_OPERATOR);
				// globs have no whitespace, do not appear in arithmetic expressions
				if (cmdState != BASH_CMD_ARITH && sc.ch == '(' && sc.chNext != '(') {
					int i = GlobScan(sc);
					if (i > 1) {
						sc.SetState(SCE_SH_IDENTIFIER);
						sc.Forward(i);
						continue;
					}
				}
				// handle opening delimiters for test/arithmetic expressions - ((,[[,[
				if (cmdState == BASH_CMD_START
				 || cmdState == BASH_CMD_BODY) {
					if (sc.Match('(', '(')) {
						cmdState = BASH_CMD_ARITH;
						sc.Forward();
					} else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) {
						cmdState = BASH_CMD_TEST;
						testExprType = 1;
						sc.Forward();
					} else if (sc.ch == '[' && IsASpace(sc.chNext)) {
						cmdState = BASH_CMD_TEST;
						testExprType = 2;
					}
				}
				// special state -- for ((x;y;z)) in ... looping
				if (cmdState == BASH_CMD_WORD && sc.Match('(', '(')) {
					cmdState = BASH_CMD_ARITH;
					sc.Forward();
					continue;
				}
				// handle command delimiters in command START|BODY|WORD state, also TEST if 'test'
				if (cmdState == BASH_CMD_START
				 || cmdState == BASH_CMD_BODY
				 || cmdState == BASH_CMD_WORD
				 || (cmdState == BASH_CMD_TEST && testExprType == 0)) {
					s[0] = static_cast<char>(sc.ch);
					if (setBashOperator.Contains(sc.chNext)) {
						s[1] = static_cast<char>(sc.chNext);
						s[2] = '\0';
						isCmdDelim = cmdDelimiter.InList(s);
						if (isCmdDelim)
							sc.Forward();
					}
					if (!isCmdDelim) {
						s[1] = '\0';
						isCmdDelim = cmdDelimiter.InList(s);
					}
					if (isCmdDelim) {
						cmdState = BASH_CMD_DELIM;
						continue;
					}
				}
				// handle closing delimiters for test/arithmetic expressions - )),]],]
				if (cmdState == BASH_CMD_ARITH && sc.Match(')', ')')) {
					cmdState = BASH_CMD_BODY;
					sc.Forward();
				} else if (cmdState == BASH_CMD_TEST && IsASpace(sc.chPrev)) {
					if (sc.Match(']', ']') && testExprType == 1) {
						sc.Forward();
						cmdState = BASH_CMD_BODY;
					} else if (sc.ch == ']' && testExprType == 2) {
						cmdState = BASH_CMD_BODY;
					}
				}
			}
		}// sc.state
	}
	sc.Complete();
	if (sc.state == SCE_SH_HERE_Q) {
		styler.ChangeLexerState(sc.currentPos, styler.Length());
	}
	sc.Complete();
}
Example #15
0
static void FoldABAQUSDoc(unsigned int startPos, int length, int,
WordList *[], Accessor &styler) {
    int startLine = styler.GetLine(startPos) ;
    int endLine   = styler.GetLine(startPos+length-1) ;

    // bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
    // We want to deal with all the cases
    // To know the correct indentlevel, we need to look back to the
    // previous command line indentation level
	// order of formatting keyline datalines commentlines
    int beginData    = -1 ;
    int beginComment = -1 ;
    int prvKeyLine   = startLine ;
    int prvKeyLineTp =  0 ;

    // Scan until we find the previous keyword line
    // this will give us the level reference that we need
    while ( prvKeyLine > 0 ) {
        prvKeyLine-- ;
        prvKeyLineTp = LineType(prvKeyLine, styler) ;
        if ( prvKeyLineTp & 4 )
            break ;
    }

    // Determine the base line level of all lines following
    // the previous keyword
    // new keyword lines are placed on this level
    //if ( prvKeyLineTp & 4 ) {
    int level = styler.LevelAt(prvKeyLine) & ~SC_FOLDLEVELHEADERFLAG ;
    //}

    // uncomment line below if weird behaviour continues
    prvKeyLine = -1 ;

    // Now start scanning over the lines.
    for ( int line = startLine; line <= endLine; line++ ) {
        int lineType = LineType(line, styler) ;

        // Check for comment line
        if ( lineType == 8 ) {
            if ( beginComment < 0 ) {
                beginComment = line ;
			}
        }

        // Check for data line
        if ( (lineType == 1) || (lineType == 3) ) {
            if ( beginData < 0 ) {
                if ( beginComment >= 0 ) {
                    beginData = beginComment ;
                } else {
                    beginData = line ;
                }
            }
			beginComment = -1 ;
		}

        // Check for keywordline.
        // As soon as a keyword line is encountered, we can set the
        // levels of everything from the previous keyword line to this one
        if ( lineType & 4 ) {
            // this is a keyword, we can now place the previous keyword
            // all its data lines and the remainder

            // Write comments and data line
            if ( beginComment < 0 ) {
                beginComment = line ;
			}

            if ( beginData < 0 ) {
                beginData = beginComment ;
				if ( prvKeyLineTp != 5 )
					SafeSetLevel(prvKeyLine, level, styler) ;
				else
					SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
            } else {
                SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
            }

            int datLevel = level + 1 ;
			if ( !(prvKeyLineTp & 4) ) {
				datLevel = level ;
			}

            for ( int ll = beginData; ll < beginComment; ll++ )
                SafeSetLevel(ll, datLevel, styler) ;

            // The keyword we just found is going to be written at another level
            // if we have a type 5 and type 6
            if ( prvKeyLineTp == 5 ) {
                level += 1 ;
			}

            if ( prvKeyLineTp == 6 ) {
                level -= 1 ;
				if ( level < 0 ) {
					level = 0 ;
				}
            }

            for ( int lll = beginComment; lll < line; lll++ )
                SafeSetLevel(lll, level, styler) ;

            // wrap and reset
            beginComment = -1 ;
            beginData    = -1 ;
            prvKeyLine   = line ;
            prvKeyLineTp = lineType ;
        }

    }

    if ( beginComment < 0 ) {
        beginComment = endLine + 1 ;
    } else {
        // We need to find out whether this comment block is followed by
        // a data line or a keyword line
        const int docLines = styler.GetLine(styler.Length() - 1);

        for ( int line = endLine + 1; line <= docLines; line++ ) {
            int lineType = LineType(line, styler) ;

            if ( lineType != 8 ) {
				if ( !(lineType & 4) )  {
					beginComment = endLine + 1 ;
				}
                break ;
			}
        }
    }

    if ( beginData < 0 ) {
        beginData = beginComment ;
		if ( prvKeyLineTp != 5 )
			SafeSetLevel(prvKeyLine, level, styler) ;
		else
			SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
    } else {
        SafeSetLevel(prvKeyLine, level | SC_FOLDLEVELHEADERFLAG, styler) ;
    }

    int datLevel = level + 1 ;
	if ( !(prvKeyLineTp & 4) ) {
		datLevel = level ;
	}

    for ( int ll = beginData; ll < beginComment; ll++ )
        SafeSetLevel(ll, datLevel, styler) ;

	if ( prvKeyLineTp == 5 ) {
		level += 1 ;
	}

	if ( prvKeyLineTp == 6 ) {
		level -= 1 ;
	}
	for ( int m = beginComment; m <= endLine; m++ )
        SafeSetLevel(m, level, styler) ;
}
Example #16
0
static void ColourisePSDoc(
    unsigned int startPos,
    int length,
    int initStyle,
    WordList *keywordlists[],
    Accessor &styler) {

    WordList &keywords1 = *keywordlists[0];
    WordList &keywords2 = *keywordlists[1];
    WordList &keywords3 = *keywordlists[2];
    WordList &keywords4 = *keywordlists[3];
    WordList &keywords5 = *keywordlists[4];

    StyleContext sc(startPos, length, initStyle, styler);

    bool tokenizing = styler.GetPropertyInt("ps.tokenize") != 0;
    int pslevel = styler.GetPropertyInt("ps.level", 3);
    int lineCurrent = styler.GetLine(startPos);
    int nestTextCurrent = 0;
    if (lineCurrent > 0 && initStyle == SCE_PS_TEXT)
        nestTextCurrent = styler.GetLineState(lineCurrent - 1);
    int numRadix = 0;
    bool numHasPoint = false;
    bool numHasExponent = false;
    bool numHasSign = false;

    // Clear out existing tokenization
    if (tokenizing && length > 0) {
        styler.StartAt(startPos, static_cast<char>(INDIC2_MASK));
        styler.ColourTo(startPos + length-1, 0);
        styler.Flush();
        styler.StartAt(startPos);
        styler.StartSegment(startPos);
    }

    for (; sc.More(); sc.Forward()) {
        if (sc.atLineStart)
            lineCurrent = styler.GetLine(sc.currentPos);

        // Determine if the current state should terminate.
        if (sc.state == SCE_PS_COMMENT || sc.state == SCE_PS_DSC_VALUE) {
            if (sc.atLineEnd) {
                sc.SetState(SCE_C_DEFAULT);
            }
        } else if (sc.state == SCE_PS_DSC_COMMENT) {
            if (sc.ch == ':') {
                sc.Forward();
                if (!sc.atLineEnd)
                    sc.SetState(SCE_PS_DSC_VALUE);
                else
                    sc.SetState(SCE_C_DEFAULT);
            } else if (sc.atLineEnd) {
                sc.SetState(SCE_C_DEFAULT);
            } else if (IsAWhitespaceChar(sc.ch) && sc.ch != '\r') {
                sc.ChangeState(SCE_PS_COMMENT);
            }
        } else if (sc.state == SCE_PS_NUMBER) {
            if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {
                if ((sc.chPrev == '+' || sc.chPrev == '-' ||
                     sc.chPrev == 'E' || sc.chPrev == 'e') && numRadix == 0)
                    sc.ChangeState(SCE_PS_NAME);
                sc.SetState(SCE_C_DEFAULT);
            } else if (sc.ch == '#') {
                if (numHasPoint || numHasExponent || numHasSign || numRadix != 0) {
                    sc.ChangeState(SCE_PS_NAME);
                } else {
                    char szradix[5];
                    sc.GetCurrent(szradix, 4);
                    numRadix = atoi(szradix);
                    if (numRadix < 2 || numRadix > 36)
                        sc.ChangeState(SCE_PS_NAME);
                }
            } else if ((sc.ch == 'E' || sc.ch == 'e') && numRadix == 0) {
                if (numHasExponent) {
                    sc.ChangeState(SCE_PS_NAME);
                } else {
                    numHasExponent = true;
                    if (sc.chNext == '+' || sc.chNext == '-')
                        sc.Forward();
                }
            } else if (sc.ch == '.') {
                if (numHasPoint || numHasExponent || numRadix != 0) {
                    sc.ChangeState(SCE_PS_NAME);
                } else {
                    numHasPoint = true;
                }
            } else if (numRadix == 0) {
                if (!IsABaseNDigit(sc.ch, 10))
                    sc.ChangeState(SCE_PS_NAME);
            } else {
                if (!IsABaseNDigit(sc.ch, numRadix))
                    sc.ChangeState(SCE_PS_NAME);
            }
        } else if (sc.state == SCE_PS_NAME || sc.state == SCE_PS_KEYWORD) {
            if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch)) {
                char s[100];
                sc.GetCurrent(s, sizeof(s));
                if ((pslevel >= 1 && keywords1.InList(s)) ||
                    (pslevel >= 2 && keywords2.InList(s)) ||
                    (pslevel >= 3 && keywords3.InList(s)) ||
                    keywords4.InList(s) || keywords5.InList(s)) {
                    sc.ChangeState(SCE_PS_KEYWORD);
                }
                sc.SetState(SCE_C_DEFAULT);
            }
        } else if (sc.state == SCE_PS_LITERAL || sc.state == SCE_PS_IMMEVAL) {
            if (IsASelfDelimitingChar(sc.ch) || IsAWhitespaceChar(sc.ch))
                sc.SetState(SCE_C_DEFAULT);
        } else if (sc.state == SCE_PS_PAREN_ARRAY || sc.state == SCE_PS_PAREN_DICT ||
                   sc.state == SCE_PS_PAREN_PROC) {
            sc.SetState(SCE_C_DEFAULT);
        } else if (sc.state == SCE_PS_TEXT) {
            if (sc.ch == '(') {
                nestTextCurrent++;
            } else if (sc.ch == ')') {
                if (--nestTextCurrent == 0)
                   sc.ForwardSetState(SCE_PS_DEFAULT);
            } else if (sc.ch == '\\') {
                sc.Forward();
            }
        } else if (sc.state == SCE_PS_HEXSTRING) {
            if (sc.ch == '>') {
                sc.ForwardSetState(SCE_PS_DEFAULT);
            } else if (!IsABaseNDigit(sc.ch, 16) && !IsAWhitespaceChar(sc.ch)) {
                sc.SetState(SCE_PS_HEXSTRING);
                styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
            }
        } else if (sc.state == SCE_PS_BASE85STRING) {
            if (sc.Match('~', '>')) {
                sc.Forward();
                sc.ForwardSetState(SCE_PS_DEFAULT);
            } else if (!IsABase85Char(sc.ch) && !IsAWhitespaceChar(sc.ch)) {
                sc.SetState(SCE_PS_BASE85STRING);
                styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
            }
        }

        // Determine if a new state should be entered.
        if (sc.state == SCE_C_DEFAULT) {
            unsigned int tokenpos = sc.currentPos;

            if (sc.ch == '[' || sc.ch == ']') {
                sc.SetState(SCE_PS_PAREN_ARRAY);
            } else if (sc.ch == '{' || sc.ch == '}') {
                sc.SetState(SCE_PS_PAREN_PROC);
            } else if (sc.ch == '/') {
                if (sc.chNext == '/') {
                    sc.SetState(SCE_PS_IMMEVAL);
                    sc.Forward();
                } else {
                    sc.SetState(SCE_PS_LITERAL);
                }
            } else if (sc.ch == '<') {
                if (sc.chNext == '<') {
                    sc.SetState(SCE_PS_PAREN_DICT);
                    sc.Forward();
                } else if (sc.chNext == '~') {
                    sc.SetState(SCE_PS_BASE85STRING);
                    sc.Forward();
                } else {
                    sc.SetState(SCE_PS_HEXSTRING);
                }
            } else if (sc.ch == '>' && sc.chNext == '>') {
                    sc.SetState(SCE_PS_PAREN_DICT);
                    sc.Forward();
            } else if (sc.ch == '>' || sc.ch == ')') {
                sc.SetState(SCE_C_DEFAULT);
                styler.ColourTo(sc.currentPos, SCE_PS_BADSTRINGCHAR);
            } else if (sc.ch == '(') {
                sc.SetState(SCE_PS_TEXT);
                nestTextCurrent = 1;
            } else if (sc.ch == '%') {
                if (sc.chNext == '%' && sc.atLineStart) {
                    sc.SetState(SCE_PS_DSC_COMMENT);
                    sc.Forward();
                    if (sc.chNext == '+') {
                        sc.Forward();
                        sc.ForwardSetState(SCE_PS_DSC_VALUE);
                    }
                } else {
                    sc.SetState(SCE_PS_COMMENT);
                }
            } else if ((sc.ch == '+' || sc.ch == '-' || sc.ch == '.') &&
                       IsABaseNDigit(sc.chNext, 10)) {
                sc.SetState(SCE_PS_NUMBER);
                numRadix = 0;
                numHasPoint = (sc.ch == '.');
                numHasExponent = false;
                numHasSign = (sc.ch == '+' || sc.ch == '-');
            } else if ((sc.ch == '+' || sc.ch == '-') && sc.chNext == '.' &&
                       IsABaseNDigit(sc.GetRelative(2), 10)) {
                sc.SetState(SCE_PS_NUMBER);
                numRadix = 0;
                numHasPoint = false;
                numHasExponent = false;
                numHasSign = true;
            } else if (IsABaseNDigit(sc.ch, 10)) {
                sc.SetState(SCE_PS_NUMBER);
                numRadix = 0;
                numHasPoint = false;
                numHasExponent = false;
                numHasSign = false;
            } else if (!IsAWhitespaceChar(sc.ch)) {
                sc.SetState(SCE_PS_NAME);
            }

            // Mark the start of tokens
            if (tokenizing && sc.state != SCE_C_DEFAULT && sc.state != SCE_PS_COMMENT &&
                sc.state != SCE_PS_DSC_COMMENT && sc.state != SCE_PS_DSC_VALUE) {
                styler.Flush();
                styler.StartAt(tokenpos, static_cast<char>(INDIC2_MASK));
                styler.ColourTo(tokenpos, INDIC2_MASK);
                styler.Flush();
                styler.StartAt(tokenpos);
                styler.StartSegment(tokenpos);
            }
        }

        if (sc.atLineEnd)
            styler.SetLineState(lineCurrent, nestTextCurrent);
    }

    sc.Complete();
}
Example #17
0
//=============================================================================
// Folding the code
static void FoldNoBoxVHDLDoc(
  unsigned int startPos,
  int length,
  int,
  Accessor &styler)
{
  // Decided it would be smarter to have the lexer have all keywords included. Therefore I
  // don't check if the style for the keywords that I use to adjust the levels.
  char words[] =
    "architecture begin case component else elsif end entity generate loop package process record then "
    "procedure function when";
  WordList keywords;
  keywords.Set(words);

  bool foldComment      = styler.GetPropertyInt("fold.comment", 1) != 0;
  bool foldCompact      = styler.GetPropertyInt("fold.compact", 1) != 0;
  bool foldAtElse       = styler.GetPropertyInt("fold.at.else", 1) != 0;
  bool foldAtBegin      = styler.GetPropertyInt("fold.at.Begin", 1) != 0;
  bool foldAtParenthese = styler.GetPropertyInt("fold.at.Parenthese", 1) != 0;
  //bool foldAtWhen       = styler.GetPropertyInt("fold.at.When", 1) != 0;  //< fold at when in case statements

  int  visibleChars     = 0;
  unsigned int endPos   = startPos + length;

  int lineCurrent       = styler.GetLine(startPos);
  int levelCurrent      = SC_FOLDLEVELBASE;
  if(lineCurrent > 0)
    levelCurrent        = styler.LevelAt(lineCurrent-1) >> 16;
  //int levelMinCurrent   = levelCurrent;
  int levelMinCurrentElse = levelCurrent;   //< Used for folding at 'else'
  int levelMinCurrentBegin = levelCurrent;  //< Used for folding at 'begin'
  int levelNext         = levelCurrent;

  /***************************************/
  int lastStart         = 0;
  char prevWord[32]     = "";

  /***************************************/
  // Find prev word
  // The logic for going up or down a level depends on a the previous keyword
  // This code could be cleaned up.
  int end = 0;
  unsigned int j;
  for(j = startPos; j>0; j--)
  {
    char ch       = styler.SafeGetCharAt(j);
    char chPrev   = styler.SafeGetCharAt(j-1);
    int style     = styler.StyleAt(j);
    int stylePrev = styler.StyleAt(j-1);
    if ((stylePrev != SCE_VHDL_COMMENT) && (stylePrev != SCE_VHDL_STRING))
    {
      if(IsAWordChar(chPrev) && !IsAWordChar(ch))
      {
        end = j-1;
      }
    }
    if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
    {
      if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0))
      {
        char s[32];
        unsigned int k;
        for(k=0; (k<31 ) && (k<end-j+1 ); k++) {
          s[k] = static_cast<char>(tolower(styler[j+k]));
        }
        s[k] = '\0';

        if(keywords.InList(s)) {
          strcpy(prevWord, s);
          break;
        }
      }
    }
  }
  for(j=j+static_cast<unsigned int>(strlen(prevWord)); j<endPos; j++)
  {
    char ch       = styler.SafeGetCharAt(j);
    int style     = styler.StyleAt(j);
    if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
    {
      if((ch == ';') && (strcmp(prevWord, "end") == 0))
      {
        strcpy(prevWord, ";");
      }
    }
  }

  char  chNext          = styler[startPos];
  char  chPrev          = '\0';
  char  chNextNonBlank;
  int   styleNext       = styler.StyleAt(startPos);
  //Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent);

  /***************************************/
  for (unsigned int i = startPos; i < endPos; i++)
  {
    char ch         = chNext;
    chNext          = styler.SafeGetCharAt(i + 1);
    chPrev          = styler.SafeGetCharAt(i - 1);
    chNextNonBlank  = chNext;
    unsigned int j  = i+1;
    while(IsABlank(chNextNonBlank) && j<endPos)
    {
      j ++ ;
      chNextNonBlank = styler.SafeGetCharAt(j);
    }
    int style           = styleNext;
    styleNext       = styler.StyleAt(i + 1);
    bool atEOL      = (ch == '\r' && chNext != '\n') || (ch == '\n');

    if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
    {
      if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler))
      {
        levelNext++;
      }
      else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler))
      {
        levelNext--;
      }
    }

    if ((style == SCE_VHDL_OPERATOR) && foldAtParenthese)
    {
      if(ch == '(') {
        levelNext++;
      } else if (ch == ')') {
        levelNext--;
      }
    }

    if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
    {
      if((ch == ';') && (strcmp(prevWord, "end") == 0))
      {
        strcpy(prevWord, ";");
      }

      if(!IsAWordChar(chPrev) && IsAWordStart(ch))
      {
        lastStart = i;
      }

      if(iswordchar(ch) && !iswordchar(chNext)) {
        char s[32];
        unsigned int k;
        for(k=0; (k<31 ) && (k<i-lastStart+1 ); k++) {
          s[k] = static_cast<char>(tolower(styler[lastStart+k]));
        }
        s[k] = '\0';

        if(keywords.InList(s))
        {
          if (
            strcmp(s, "architecture") == 0  ||
            strcmp(s, "case") == 0          ||
            strcmp(s, "component") == 0     ||
            strcmp(s, "entity") == 0        ||
            strcmp(s, "generate") == 0      ||
            strcmp(s, "loop") == 0          ||
            strcmp(s, "package") ==0        ||
            strcmp(s, "process") == 0       ||
            strcmp(s, "record") == 0        ||
            strcmp(s, "then") == 0)
          {
            if (strcmp(prevWord, "end") != 0)
            {
              if (levelMinCurrentElse > levelNext) {
                levelMinCurrentElse = levelNext;
              }
              levelNext++;
            }
          } else if (
            strcmp(s, "procedure") == 0     ||
            strcmp(s, "function") == 0)
          {
            if (strcmp(prevWord, "end") != 0) // check for "end procedure" etc.
            { // This code checks to see if the procedure / function is a definition within a "package"
              // rather than the actual code in the body.
              int BracketLevel = 0;
              for(int j=i+1; j<styler.Length(); j++)
              {
                int LocalStyle = styler.StyleAt(j);
                char LocalCh = styler.SafeGetCharAt(j);
                if(LocalCh == '(') BracketLevel++;
                if(LocalCh == ')') BracketLevel--;
                if(
                  (BracketLevel == 0) &&
                  (LocalStyle != SCE_VHDL_COMMENT) &&
                  (LocalStyle != SCE_VHDL_STRING) &&
                  !iswordchar(styler.SafeGetCharAt(j-1)) &&
                  styler.Match(j, "is") &&
                  !iswordchar(styler.SafeGetCharAt(j+2)))
                {
                  if (levelMinCurrentElse > levelNext) {
                    levelMinCurrentElse = levelNext;
                  }
                  levelNext++;
                  break;
                }
                if((BracketLevel == 0) && (LocalCh == ';'))
                {
                  break;
                }
              }
            }

          } else if (strcmp(s, "end") == 0) {
            levelNext--;
          }  else if(strcmp(s, "elsif") == 0) { // elsif is followed by then so folding occurs correctly
            levelNext--;
          } else if (strcmp(s, "else") == 0) {
            if(strcmp(prevWord, "when") != 0)  // ignore a <= x when y else z;
            {
              levelMinCurrentElse = levelNext - 1;  // VHDL else is all on its own so just dec. the min level
            }
          } else if(
            ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "architecture") == 0)) ||
            ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) ||
            ((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0)))
          {
            levelMinCurrentBegin = levelNext - 1;
          }
          //Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent);
          strcpy(prevWord, s);
        }
      }
    }
    if (atEOL) {
      int levelUse = levelCurrent;

      if (foldAtElse && (levelMinCurrentElse < levelUse)) {
        levelUse = levelMinCurrentElse;
      }
      if (foldAtBegin && (levelMinCurrentBegin < levelUse)) {
        levelUse = levelMinCurrentBegin;
      }
      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);
      }
      //Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent);
      lineCurrent++;
      levelCurrent = levelNext;
      //levelMinCurrent = levelCurrent;
      levelMinCurrentElse = levelCurrent;
      levelMinCurrentBegin = levelCurrent;
      visibleChars = 0;
    }
    /***************************************/
    if (!isspacechar(ch)) visibleChars++;
  }

  /***************************************/
//  Platform::DebugPrintf("Line[%04d] ---------------------------------------------------- Level[%x]\n", lineCurrent+1, levelCurrent);
}
Example #18
0
static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
        WordList *keywordlists[], Accessor &styler) {

	int endPos = startPos + length;

	// Backtrack to previous line in case need to fix its tab whinging
	int lineCurrent = styler.GetLine(startPos);
	if (startPos > 0) {
		if (lineCurrent > 0) {
			lineCurrent--;
			// Look for backslash-continued lines
			while (lineCurrent > 0) {
				int eolPos = styler.LineStart(lineCurrent) - 1;
				int eolStyle = styler.StyleAt(eolPos);
				if (eolStyle == SCE_P_STRING
				    || eolStyle == SCE_P_CHARACTER
				    || eolStyle == SCE_P_STRINGEOL) {
					lineCurrent -= 1;
				} else {
					break;
				}
			}
			startPos = styler.LineStart(lineCurrent);
		}
		initStyle = startPos == 0 ? SCE_P_DEFAULT : styler.StyleAt(startPos - 1);
	}

	WordList &keywords = *keywordlists[0];
	WordList &keywords2 = *keywordlists[1];
	WordList &keywords3 = *keywordlists[2];

	// property tab.timmy.whinge.level
	//	For Python code, checks whether indenting is consistent.
	//	The default, 0 turns off indentation checking,
	//	1 checks whether each line is potentially inconsistent with the previous line,
	//	2 checks whether any space characters occur before a tab character in the indentation,
	//	3 checks whether any spaces are in the indentation, and
	//	4 checks for any tab characters in the indentation.
	//	1 is a good level to use.
	const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");

	// property lexer.python.literals.binary
	//	Set to 0 to not recognise Python 3 binary and octal literals: 0b1011 0o712.
	bool base2or8Literals = styler.GetPropertyInt("lexer.python.literals.binary", 1) != 0;

	// property lexer.python.strings.u
	//	Set to 0 to not recognise Python Unicode literals u"x" as used before Python 3.
	literalsAllowed allowedLiterals = (styler.GetPropertyInt("lexer.python.strings.u", 1)) ? litU : litNone;

	// property lexer.python.strings.b
	//	Set to 0 to not recognise Python 3 bytes literals b"x".
	if (styler.GetPropertyInt("lexer.python.strings.b", 1))
		allowedLiterals = static_cast<literalsAllowed>(allowedLiterals | litB);

	// property lexer.python.strings.over.newline
	//      Set to 1 to allow strings to span newline characters.
	bool stringsOverNewline = styler.GetPropertyInt("lexer.python.strings.over.newline") != 0;

	// property lexer.python.keywords2.no.sub.identifiers
	//	When enabled, it will not style keywords2 items that are used as a sub-identifier.
	//      Example: when set, will not highlight "foo.open" when "open" is a keywords2 item.
	const bool keywords2NoSubIdentifiers = styler.GetPropertyInt("lexer.python.keywords2.no.sub.identifiers") != 0;

	initStyle = initStyle & 31;
	if (initStyle == SCE_P_STRINGEOL) {
		initStyle = SCE_P_DEFAULT;
	}

	kwType kwLast = kwOther;
	int spaceFlags = 0;
	styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
	bool base_n_number = false;

	StyleContext sc(startPos, endPos - startPos, initStyle, styler);

	bool indentGood = true;
	int startIndicator = sc.currentPos;
	bool inContinuedString = false;

	for (; sc.More(); sc.Forward()) {

		if (sc.atLineStart) {
			styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
			indentGood = true;
			if (whingeLevel == 1) {
				indentGood = (spaceFlags & wsInconsistent) == 0;
			} else if (whingeLevel == 2) {
				indentGood = (spaceFlags & wsSpaceTab) == 0;
			} else if (whingeLevel == 3) {
				indentGood = (spaceFlags & wsSpace) == 0;
			} else if (whingeLevel == 4) {
				indentGood = (spaceFlags & wsTab) == 0;
			}
			if (!indentGood) {
				styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
				startIndicator = sc.currentPos;
			}
		}

		if (sc.atLineEnd) {
			if ((sc.state == SCE_P_DEFAULT) ||
			        (sc.state == SCE_P_TRIPLE) ||
			        (sc.state == SCE_P_TRIPLEDOUBLE)) {
				// Perform colourisation of white space and triple quoted strings at end of each line to allow
				// tab marking to work inside white space and triple quoted strings
				sc.SetState(sc.state);
			}
			lineCurrent++;
			if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
				if (inContinuedString || stringsOverNewline) {
					inContinuedString = false;
				} else {
					sc.ChangeState(SCE_P_STRINGEOL);
					sc.ForwardSetState(SCE_P_DEFAULT);
				}
			}
			if (!sc.More())
				break;
		}

		bool needEOLCheck = false;

		// Check for a state end
		if (sc.state == SCE_P_OPERATOR) {
			kwLast = kwOther;
			sc.SetState(SCE_P_DEFAULT);
		} else if (sc.state == SCE_P_NUMBER) {
			if (!IsAWordChar(sc.ch) &&
			        !(!base_n_number && ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
				sc.SetState(SCE_P_DEFAULT);
			}
		} else if (sc.state == SCE_P_IDENTIFIER) {
			if ((sc.ch == '.') || (!IsAWordChar(sc.ch))) {
				char s[100];
				sc.GetCurrent(s, sizeof(s));
				int style = SCE_P_IDENTIFIER;
				if ((kwLast == kwImport) && (strcmp(s, "as") == 0)) {
					style = SCE_P_WORD;
				} else if (keywords.InList(s)) {
					style = SCE_P_WORD;
				} else if (kwLast == kwClass) {
					style = SCE_P_CLASSNAME;
				} else if (kwLast == kwDef) {
					style = SCE_P_DEFNAME;
				} else if (kwLast == kwCDef || kwLast == kwCPDef) {
					int pos = sc.currentPos;
					unsigned char ch = styler.SafeGetCharAt(pos, '\0');
					while (ch != '\0') {
						if (ch == '(') {
							style = SCE_P_DEFNAME;
							break;
						} else if (ch == ':') {
							style = SCE_P_CLASSNAME;
							break;
						} else if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
							pos++;
							ch = styler.SafeGetCharAt(pos, '\0');
						} else {
							break;
						}
					}
				} else if (keywords2.InList(s)) {
					if (keywords2NoSubIdentifiers) {
						// We don't want to highlight keywords2
						// that are used as a sub-identifier,
						// i.e. not open in "foo.open".
						int pos = styler.GetStartSegment() - 1;
						if (pos < 0 || (styler.SafeGetCharAt(pos, '\0') != '.'))
							style = SCE_P_WORD2;
					} else {
						style = SCE_P_WORD2;
					}
				} else if (keywords3.InList(s)) {
					style = SCE_P_WORD3;
				}
				sc.ChangeState(style);
				sc.SetState(SCE_P_DEFAULT);
				if (style == SCE_P_WORD) {
					if (0 == strcmp(s, "class"))
						kwLast = kwClass;
					else if (0 == strcmp(s, "def"))
						kwLast = kwDef;
					else if (0 == strcmp(s, "import"))
						kwLast = kwImport;
					else if (0 == strcmp(s, "cdef"))
						kwLast = kwCDef;
					else if (0 == strcmp(s, "cpdef"))
						kwLast = kwCPDef;
					else if (0 == strcmp(s, "cimport"))
						kwLast = kwImport;
					else if (kwLast != kwCDef && kwLast != kwCPDef)
						kwLast = kwOther;
				} else if (kwLast != kwCDef && kwLast != kwCPDef) {
					kwLast = kwOther;
				}
			}
		} else if ((sc.state == SCE_P_COMMENTLINE) || (sc.state == SCE_P_COMMENTBLOCK)) {
			if (sc.ch == '\r' || sc.ch == '\n') {
				sc.SetState(SCE_P_DEFAULT);
			}
		} else if (sc.state == SCE_P_DECORATOR) {
			if (!IsAWordChar(sc.ch)) {
				sc.SetState(SCE_P_DEFAULT);
			}
		} else if ((sc.state == SCE_P_STRING) || (sc.state == SCE_P_CHARACTER)) {
			if (sc.ch == '\\') {
				if ((sc.chNext == '\r') && (sc.GetRelative(2) == '\n')) {
					sc.Forward();
				}
				if (sc.chNext == '\n' || sc.chNext == '\r') {
					inContinuedString = true;
				} else {
					// Don't roll over the newline.
					sc.Forward();
				}
			} else if ((sc.state == SCE_P_STRING) && (sc.ch == '\"')) {
				sc.ForwardSetState(SCE_P_DEFAULT);
				needEOLCheck = true;
			} else if ((sc.state == SCE_P_CHARACTER) && (sc.ch == '\'')) {
				sc.ForwardSetState(SCE_P_DEFAULT);
				needEOLCheck = true;
			}
		} else if (sc.state == SCE_P_TRIPLE) {
			if (sc.ch == '\\') {
				sc.Forward();
			} else if (sc.Match("\'\'\'")) {
				sc.Forward();
				sc.Forward();
				sc.ForwardSetState(SCE_P_DEFAULT);
				needEOLCheck = true;
			}
		} else if (sc.state == SCE_P_TRIPLEDOUBLE) {
			if (sc.ch == '\\') {
				sc.Forward();
			} else if (sc.Match("\"\"\"")) {
				sc.Forward();
				sc.Forward();
				sc.ForwardSetState(SCE_P_DEFAULT);
				needEOLCheck = true;
			}
		}

		if (!indentGood && !IsASpaceOrTab(sc.ch)) {
			styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 1);
			startIndicator = sc.currentPos;
			indentGood = true;
		}

		// One cdef or cpdef line, clear kwLast only at end of line
		if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
			kwLast = kwOther;
		}

		// State exit code may have moved on to end of line
		if (needEOLCheck && sc.atLineEnd) {
			lineCurrent++;
			styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
			if (!sc.More())
				break;
		}

		// Check for a new state starting character
		if (sc.state == SCE_P_DEFAULT) {
			if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
				if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
					base_n_number = true;
					sc.SetState(SCE_P_NUMBER);
				} else if (sc.ch == '0' &&
					(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
					if (base2or8Literals) {
						base_n_number = true;
						sc.SetState(SCE_P_NUMBER);
					} else {
						sc.SetState(SCE_P_NUMBER);
						sc.ForwardSetState(SCE_P_IDENTIFIER);
					}
				} else {
					base_n_number = false;
					sc.SetState(SCE_P_NUMBER);
				}
			} else if ((IsASCII(sc.ch) && isoperator(static_cast<char>(sc.ch))) || sc.ch == '`') {
				sc.SetState(SCE_P_OPERATOR);
			} else if (sc.ch == '#') {
				sc.SetState(sc.chNext == '#' ? SCE_P_COMMENTBLOCK : SCE_P_COMMENTLINE);
			} else if (sc.ch == '@') {
				sc.SetState(SCE_P_DECORATOR);
			} else if (IsPyStringStart(sc.ch, sc.chNext, sc.GetRelative(2), allowedLiterals)) {
				unsigned int nextIndex = 0;
				sc.SetState(GetPyStringState(styler, sc.currentPos, &nextIndex, allowedLiterals));
				while (nextIndex > (sc.currentPos + 1) && sc.More()) {
					sc.Forward();
				}
			} else if (IsAWordStart(sc.ch)) {
				sc.SetState(SCE_P_IDENTIFIER);
			}
		}
	}
	styler.IndicatorFill(startIndicator, sc.currentPos, indicatorWhitespace, 0);
	sc.Complete();
}
Example #19
0
static void FoldTACLDoc(unsigned int startPos, int length, int initStyle, WordList *[],
                            Accessor &styler) {
	bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
	bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
	bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
	unsigned int endPos = startPos + length;
	int visibleChars = 0;
	int lineCurrent = styler.GetLine(startPos);
	int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
	int levelCurrent = levelPrev;
	char chNext = styler[startPos];
	int styleNext = styler.StyleAt(startPos);
	int style = initStyle;
	bool section = false;

	int lastStart = 0;

	for (unsigned int i = startPos; i < endPos; i++) {
		char ch = chNext;
		chNext = styler.SafeGetCharAt(i + 1);
		int stylePrev = style;
		style = styleNext;
		styleNext = styler.StyleAt(i + 1);
		bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');

		if (stylePrev == SCE_C_DEFAULT && (style == SCE_C_WORD || style == SCE_C_PREPROCESSOR))
		{
			// Store last word start point.
			lastStart = i;
		}

		if (stylePrev == SCE_C_WORD || stylePrev == SCE_C_PREPROCESSOR) {
			if(isTACLwordchar(ch) && !isTACLwordchar(chNext)) {
				char s[100];
				getRange(lastStart, i, styler, s, sizeof(s));
				if (stylePrev == SCE_C_PREPROCESSOR && strcmp(s, "?section") == 0)
					{
					section = true;
					levelCurrent = 1;
					levelPrev = 0;
					}
				else if (stylePrev == SCE_C_WORD)
					levelCurrent += classifyFoldPointTACL(s);
			}
		}

		if (style == SCE_C_OPERATOR) {
			if (ch == '[') {
				levelCurrent++;
			} else if (ch == ']') {
				levelCurrent--;
			}
		}
		if (foldComment && (style == SCE_C_COMMENTLINE)) {
			if ((ch == '/') && (chNext == '/')) {
				char chNext2 = styler.SafeGetCharAt(i + 2);
				if (chNext2 == '{') {
					levelCurrent++;
				} else if (chNext2 == '}') {
					levelCurrent--;
				}
			}
		}

		if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
			if (ch == '{' && chNext == '$') {
				unsigned int j=i+2; // skip {$
				while ((j<endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
					j++;
				}
				if (styler.Match(j, "region") || styler.Match(j, "if")) {
					levelCurrent++;
				} else if (styler.Match(j, "end")) {
					levelCurrent--;
				}
			}
		}

		if (foldComment && IsStreamCommentStyle(style)) {
			if (!IsStreamCommentStyle(stylePrev)) {
				levelCurrent++;
			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
				// Comments don't end at end of line and the next character may be unstyled.
				levelCurrent--;
			}
		}
		if (atEOL) {
			int lev = levelPrev | SC_FOLDLEVELBASE;
			if (visibleChars == 0 && foldCompact)
				lev |= SC_FOLDLEVELWHITEFLAG;
			if ((levelCurrent > levelPrev || section) && (visibleChars > 0))
				lev |= SC_FOLDLEVELHEADERFLAG;
			if (lev != styler.LevelAt(lineCurrent)) {
				styler.SetLevel(lineCurrent, lev);
			}
			lineCurrent++;
			levelPrev = levelCurrent;
			visibleChars = 0;
			section = false;
		}

		if (!isspacechar(ch))
			visibleChars++;
	}

	// Fill in the real level of the next line, keeping the current flags as they will be filled in later
	int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
	styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
Example #20
0
static bool IsQuoteLine(int line, Accessor &styler) {
	int style = styler.StyleAt(styler.LineStart(line)) & 31;
	return ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
}
Example #21
0
// Main colorizing function called by Scintilla
static void
ColouriseGui4CliDoc(unsigned int startPos, int length, int initStyle,
                    WordList *keywordlists[], Accessor &styler)
{
	styler.StartAt(startPos);

	int quotestart = 0, oldstate, currentline = styler.GetLine(startPos);
	styler.StartSegment(startPos);
	bool noforward;
	char buff[BUFFSIZE+1];	// buffer for command name

	StyleContext sc(startPos, length, initStyle, styler);
	buff[0] = '\0'; // cbuff = 0;

	if (sc.state != SCE_GC_COMMENTBLOCK) // colorize 1st word..
		colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);

	while (sc.More())
	{	noforward = 0;

		switch (sc.ch)
		{
			case '/':
				if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_STRING)
					break;
				if (sc.chNext == '/')	// line comment
				{	sc.SetState (SCE_GC_COMMENTLINE);
					sc.Forward();
					styler.ColourTo(sc.currentPos, sc.state);
				}
				else if (sc.chNext == '*')	// block comment
				{	sc.SetState(SCE_GC_COMMENTBLOCK);
					sc.Forward();
					styler.ColourTo(sc.currentPos, sc.state);
				}
				else
					styler.ColourTo(sc.currentPos, sc.state);
				break;

			case '*':	// end of comment block, or operator..
				if (sc.state == SCE_GC_STRING)
					break;
				if (sc.state == SCE_GC_COMMENTBLOCK && sc.chNext == '/')
				{	sc.Forward();
					styler.ColourTo(sc.currentPos, sc.state);
					sc.ChangeState (SCE_GC_DEFAULT);
				}
				else
					styler.ColourTo(sc.currentPos, sc.state);
				break;

			case '\'':	case '\"': // strings..
				if (sc.state == SCE_GC_COMMENTBLOCK || sc.state == SCE_GC_COMMENTLINE)
					break;
				if (sc.state == SCE_GC_STRING)
				{	if (sc.ch == quotestart)	// match same quote char..
					{	styler.ColourTo(sc.currentPos, sc.state);
						sc.ChangeState(SCE_GC_DEFAULT);
						quotestart = 0;
				}	}
				else
				{	styler.ColourTo(sc.currentPos - 1, sc.state);
					sc.ChangeState(SCE_GC_STRING);
					quotestart = sc.ch;
				}
				break;

			case ';':	// end of commandline character
				if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
					 sc.state != SCE_GC_STRING)
				{
					styler.ColourTo(sc.currentPos - 1, sc.state);
					styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
					sc.ChangeState(SCE_GC_DEFAULT);
					sc.Forward();
					colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
					noforward = 1; // don't move forward - already positioned at next char..
				}
				break;

			case '+': case '-': case '=':	case '!':	// operators..
			case '<': case '>': case '&': case '|': case '$':
				if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE &&
					 sc.state != SCE_GC_STRING)
				{
					styler.ColourTo(sc.currentPos - 1, sc.state);
					styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
					sc.ChangeState(SCE_GC_DEFAULT);
				}
				break;

			case '\\':	// escape - same as operator, but also mark in strings..
				if (sc.state != SCE_GC_COMMENTBLOCK && sc.state != SCE_GC_COMMENTLINE)
				{
					oldstate = sc.state;
					styler.ColourTo(sc.currentPos - 1, sc.state);
					sc.Forward(); // mark also the next char..
					styler.ColourTo(sc.currentPos, SCE_GC_OPERATOR);
					sc.ChangeState(oldstate);
				}
				break;

			case '\n': case '\r':
				++currentline;
				if (sc.state == SCE_GC_COMMENTLINE)
				{	styler.ColourTo(sc.currentPos, sc.state);
					sc.ChangeState (SCE_GC_DEFAULT);
				}
				else if (sc.state != SCE_GC_COMMENTBLOCK)
				{	colorFirstWord(keywordlists, styler, &sc, buff, BUFFSIZE, currentline);
					noforward = 1; // don't move forward - already positioned at next char..
				}
				break;

//			case ' ': case '\t':
//			default :
		}

		if (!noforward) sc.Forward();

	}
	sc.Complete();
}
Example #22
0
static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unused*/,
                      WordList *[], Accessor &styler) {
	const int maxPos = startPos + length;
	const int maxLines = (maxPos == styler.Length()) ? styler.GetLine(maxPos) : styler.GetLine(maxPos - 1);	// Requested last line
	const int docLines = styler.GetLine(styler.Length());	// Available last line

	// property fold.quotes.python
	//	This option enables folding multi-line quoted strings when using the Python lexer.
	const bool foldQuotes = styler.GetPropertyInt("fold.quotes.python") != 0;

	const bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;

	// Backtrack to previous non-blank line so we can determine indent level
	// for any white space lines (needed esp. within triple quoted strings)
	// and so we can fix any preceding fold level (which is why we go back
	// at least one line in all cases)
	int spaceFlags = 0;
	int lineCurrent = styler.GetLine(startPos);
	int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
	while (lineCurrent > 0) {
		lineCurrent--;
		indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, NULL);
		if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG) &&
		        (!IsCommentLine(lineCurrent, styler)) &&
		        (!IsQuoteLine(lineCurrent, styler)))
			break;
	}
	int indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;

	// Set up initial loop state
	startPos = styler.LineStart(lineCurrent);
	int prev_state = SCE_P_DEFAULT & 31;
	if (lineCurrent >= 1)
		prev_state = styler.StyleAt(startPos - 1) & 31;
	int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) || (prev_state == SCE_P_TRIPLEDOUBLE));

	// Process all characters to end of requested range or end of any triple quote
	//that hangs over the end of the range.  Cap processing in all cases
	// to end of document (in case of unclosed quote at end).
	while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) || prevQuote)) {

		// Gather info
		int lev = indentCurrent;
		int lineNext = lineCurrent + 1;
		int indentNext = indentCurrent;
		int quote = false;
		if (lineNext <= docLines) {
			// Information about next line is only available if not at end of document
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
			int lookAtPos = (styler.LineStart(lineNext) == styler.Length()) ? styler.Length() - 1 : styler.LineStart(lineNext);
			int style = styler.StyleAt(lookAtPos) & 31;
			quote = foldQuotes && ((style == SCE_P_TRIPLE) || (style == SCE_P_TRIPLEDOUBLE));
		}
		const int quote_start = (quote && !prevQuote);
		const int quote_continue = (quote && prevQuote);
		if (!quote || !prevQuote)
			indentCurrentLevel = indentCurrent & SC_FOLDLEVELNUMBERMASK;
		if (quote)
			indentNext = indentCurrentLevel;
		if (indentNext & SC_FOLDLEVELWHITEFLAG)
			indentNext = SC_FOLDLEVELWHITEFLAG | indentCurrentLevel;

		if (quote_start) {
			// Place fold point at start of triple quoted string
			lev |= SC_FOLDLEVELHEADERFLAG;
		} else if (quote_continue || prevQuote) {
			// Add level to rest of lines in the string
			lev = lev + 1;
		}

		// Skip past any blank lines for next indent level info; we skip also
		// comments (all comments, not just those starting in column 0)
		// which effectively folds them into surrounding code rather
		// than screwing up folding.

		while (!quote &&
		        (lineNext < docLines) &&
		        ((indentNext & SC_FOLDLEVELWHITEFLAG) ||
		         (lineNext <= docLines && IsCommentLine(lineNext, styler)))) {

			lineNext++;
			indentNext = styler.IndentAmount(lineNext, &spaceFlags, NULL);
		}

		const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
		const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);

		// Now set all the indent levels on the lines we skipped
		// Do this from end to start.  Once we encounter one line
		// which is indented more than the line after the end of
		// the comment-block, use the level of the block before

		int skipLine = lineNext;
		int skipLevel = levelAfterComments;

		while (--skipLine > lineCurrent) {
			int skipLineIndent = styler.IndentAmount(skipLine, &spaceFlags, NULL);

			if (foldCompact) {
				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments)
					skipLevel = levelBeforeComments;

				int whiteFlag = skipLineIndent & SC_FOLDLEVELWHITEFLAG;

				styler.SetLevel(skipLine, skipLevel | whiteFlag);
			} else {
				if ((skipLineIndent & SC_FOLDLEVELNUMBERMASK) > levelAfterComments &&
					!(skipLineIndent & SC_FOLDLEVELWHITEFLAG) &&
					!IsCommentLine(skipLine, styler))
					skipLevel = levelBeforeComments;

				styler.SetLevel(skipLine, skipLevel);
			}
		}

		// Set fold header on non-quote line
		if (!quote && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
			if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
				lev |= SC_FOLDLEVELHEADERFLAG;
		}

		// Keep track of triple quote state of previous line
		prevQuote = quote;

		// Set fold level for this line and move to next line
		styler.SetLevel(lineCurrent, foldCompact ? lev : lev & ~SC_FOLDLEVELWHITEFLAG);
		indentCurrent = indentNext;
		lineCurrent = lineNext;
	}

	// NOTE: Cannot set level of last line here because indentCurrent doesn't have
	// header flag set; the loop above is crafted to take care of this case!
	//styler.SetLevel(lineCurrent, indentCurrent);
}
Example #23
0
static void FoldMSSQLDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
  bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
  bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
  unsigned int endPos = startPos + length;
  int visibleChars = 0;
  int lineCurrent = styler.GetLine(startPos);
  int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
  int levelCurrent = levelPrev;
  char chNext = styler[startPos];
  bool inComment = (styler.StyleAt(startPos-1) == SCE_MSSQL_COMMENT);
    char s[10] = "";
  for (unsigned int i = startPos; i < endPos; i++) {
    char ch = chNext;
    chNext = styler.SafeGetCharAt(i + 1);
    int style = styler.StyleAt(i);
    bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
        // Comment folding
    if (foldComment) {
      if (!inComment && (style == SCE_MSSQL_COMMENT))
        levelCurrent++;
      else if (inComment && (style != SCE_MSSQL_COMMENT))
        levelCurrent--;
      inComment = (style == SCE_MSSQL_COMMENT);
    }
        if (style == SCE_MSSQL_STATEMENT) {
            // Folding between begin or case and end
            if (ch == 'b' || ch == 'B' || ch == 'c' || ch == 'C' || ch == 'e' || ch == 'E') {
                for (unsigned int j = 0; j < 5; j++) {
          if (!iswordchar(styler[i + j])) {
            break;
          }
          s[j] = static_cast<char>(tolower(styler[i + j]));
          s[j + 1] = '\0';
                }
        if ((strcmp(s, "begin") == 0) || (strcmp(s, "case") == 0)) {
          levelCurrent++;
        }
        if (strcmp(s, "end") == 0) {
          levelCurrent--;
        }
            }
        }
    if (atEOL) {
      int lev = levelPrev;
      if (visibleChars == 0 && foldCompact)
        lev |= SC_FOLDLEVELWHITEFLAG;
      if ((levelCurrent > levelPrev) && (visibleChars > 0))
        lev |= SC_FOLDLEVELHEADERFLAG;
      if (lev != styler.LevelAt(lineCurrent)) {
        styler.SetLevel(lineCurrent, lev);
      }
      lineCurrent++;
      levelPrev = levelCurrent;
      visibleChars = 0;
    }
    if (!isspacechar(ch))
      visibleChars++;
  }
  // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  int flagsNext = styler.LevelAt(lineCurrent) & ~SC_FOLDLEVELNUMBERMASK;
  styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
Example #24
0
// 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++;
  }
}
Example #25
0
static void FoldPowerProDoc(unsigned int startPos, int 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;

	int endPos = startPos + length;
	int 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
	int 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 (int 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);
	}

}
Example #26
0
static int LineStart(int line, Accessor &styler)
{
    return styler.LineStart(line) ;
}
Example #27
0
inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor & styler, WordList * keywordlists[] )
{
	char ch;
	const unsigned int beg = cur;

	cur++;
	for( ; ; )
	{
		ch = styler.SafeGetCharAt( cur );
		if( ( ch != '_' ) && ( ch != '-' ) &&
			!islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;

		cur++;
		if( cur >= one_too_much ) 
		{
			break;
		}
	}

	const int ide_len = cur - beg + 1;
	char * ide = new char[ ide_len ];
	getRange( beg, cur, styler, ide, ide_len );
	
	WordList & keywords    = *keywordlists[ 0 ];
	WordList & classwords  = *keywordlists[ 1 ];

	if( keywords.InList( ide ) ) // Keyword
	{
		delete [] ide;

		styler.ColourTo( cur - 1, SCE_OPAL_KEYWORD );
		if( cur >= one_too_much )
		{
			return false; // STOP
		}
		else
		{
			styler.StartSegment( cur );	
			return true;			
		}
	}
	else if( classwords.InList( ide ) ) // Sort
	{
		delete [] ide;

		styler.ColourTo( cur - 1, SCE_OPAL_SORT );
		if( cur >= one_too_much )
		{
			return false; // STOP
		}
		else
		{
			styler.StartSegment( cur );	
			return true;			
		}
	}
	else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
	{
		delete [] ide;

		styler.ColourTo( cur - 1, SCE_OPAL_BOOL_CONST );
		if( cur >= one_too_much )
		{
			return false; // STOP
		}
		else
		{
			styler.StartSegment( cur );	
			return true;			
		}
	}
	else // Unknown keyword
	{
		delete [] ide;

		styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
		if( cur >= one_too_much )
		{
			return false; // STOP
		}
		else
		{
			styler.StartSegment( cur );
			return true;			
		}
	}

}
Example #28
0
// LineType
//
// bits determines the line type
// 1  : data line
// 2  : only whitespace
// 3  : data line with only whitespace
// 4  : keyword line
// 5  : block open keyword line
// 6  : block close keyword line
// 7  : keyword line in error
// 8  : comment line
static int LineType(int line, Accessor &styler) {
    int pos = LineStart(line, styler) ;
    int eol_pos = LineEnd(line, styler) ;

    int c ;
    char ch = ' ';

    int i = pos ;
    while ( i < eol_pos ) {
        c = styler.SafeGetCharAt(i);
        ch = static_cast<char>(LowerCase(c));
        // We can say something as soon as no whitespace
        // was encountered
        if ( !IsSpace(c) )
            break ;
        i++ ;
    }

    if ( i >= eol_pos ) {
        // This is a whitespace line, currently
        // classifies as data line
        return 3 ;
    }

    if ( ch != '*' ) {
        // This is a data line
        return 1 ;
    }

    if ( i == eol_pos - 1 ) {
        // Only a single *, error but make keyword line
        return 4+3 ;
    }

    // This means we can have a second character
    // if that is also a * this means a comment
    // otherwise it is a keyword.
    c = styler.SafeGetCharAt(i+1);
    ch = static_cast<char>(LowerCase(c));
    if ( ch == '*' ) {
        return 8 ;
    }

    // At this point we know this is a keyword line
    // the character at position i is a *
    // it is not a comment line
    char word[256] ;
    int  wlen = 0;

    word[wlen] = '*' ;
	wlen++ ;

    i++ ;
    while ( (i < eol_pos) && (wlen < 255) ) {
        c = styler.SafeGetCharAt(i);
        ch = static_cast<char>(LowerCase(c));

        if ( (!IsSpace(c)) && (!IsIdentifier(c)) )
            break ;

        if ( IsIdentifier(c) ) {
            word[wlen] = ch ;
			wlen++ ;
		}

        i++ ;
    }

    word[wlen] = 0 ;

    // Make a comparison
	if ( !strcmp(word, "*step") ||
         !strcmp(word, "*part") ||
         !strcmp(word, "*instance") ||
         !strcmp(word, "*assembly")) {
       return 4+1 ;
    }

	if ( !strcmp(word, "*endstep") ||
         !strcmp(word, "*endpart") ||
         !strcmp(word, "*endinstance") ||
         !strcmp(word, "*endassembly")) {
       return 4+2 ;
    }

    return 4 ;
}
Example #29
0
inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
{
	char ch;
	
	if( could_fail )
	{
		cur++;
		if( cur >= one_too_much )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
			return false; // STOP
		}
		
		ch = styler.SafeGetCharAt( cur );
		if( ch != '*' )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
			styler.StartSegment( cur );
			return true;
		}
	}
	
	// Wait for comment close
	cur++;
	bool star_found = false;
	for( ; ; )
	{
		if( cur >= one_too_much )
		{
			styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
			return false; // STOP
		}
		
		ch = styler.SafeGetCharAt( cur );
		if( star_found )
		{
			if( ch == '/' )
			{
				styler.ColourTo( cur, SCE_OPAL_COMMENT_BLOCK );
				cur++;
				if( cur >= one_too_much )
				{
					return false; // STOP
				}
				else
				{
					styler.StartSegment( cur );
					return true;
				}
			}
			else if( ch != '*' )
			{
				star_found = false;
			}
		}
		else if( ch == '*' )
		{
			star_found = true;
		}
		cur++;
	}
}
Example #30
0
static void FoldErlangDoc(
  unsigned int startPos, int length, int initStyle,
  WordList** /*keywordlists*/, Accessor &styler
) {
  unsigned int endPos = startPos + length;
  int currentLine = styler.GetLine(startPos);
  int lev;
  int previousLevel = styler.LevelAt(currentLine) & SC_FOLDLEVELNUMBERMASK;
  int currentLevel = previousLevel;
  int styleNext = styler.StyleAt(startPos);
  int style = initStyle;
  int stylePrev;
  int keyword_start = 0;
  char ch;
  char chNext = styler.SafeGetCharAt(startPos);
  bool atEOL;

  for (unsigned int i = startPos; i < endPos; i++) {
    ch = chNext;
    chNext = styler.SafeGetCharAt(i + 1);

    // Get styles
    stylePrev = style;
    style = styleNext;
    styleNext = styler.StyleAt(i + 1);
    atEOL = ((ch == '\r') && (chNext != '\n')) || (ch == '\n');

    if (stylePrev != SCE_ERLANG_KEYWORD
      && style == SCE_ERLANG_KEYWORD) {
      keyword_start = i;
    }

    // Fold on keywords
    if (stylePrev == SCE_ERLANG_KEYWORD
      && style != SCE_ERLANG_KEYWORD
      && style != SCE_ERLANG_ATOM
    ) {
      currentLevel += ClassifyErlangFoldPoint(styler,
                          styleNext,
                          keyword_start);
    }

    // Fold on comments
    if (style == SCE_ERLANG_COMMENT
      || style == SCE_ERLANG_COMMENT_MODULE
      || style == SCE_ERLANG_COMMENT_FUNCTION) {

      if (ch == '%' && chNext == '{') {
        currentLevel++;
      } else if (ch == '%' && chNext == '}') {
        currentLevel--;
      }
    }

    // Fold on braces
    if (style == SCE_ERLANG_OPERATOR) {
      if (ch == '{' || ch == '(' || ch == '[') {
        currentLevel++;
      } else if (ch == '}' || ch == ')' || ch == ']') {
        currentLevel--;
      }
    }


    if (atEOL) {
      lev = previousLevel;

      if (currentLevel > previousLevel)
        lev |= SC_FOLDLEVELHEADERFLAG;

      if (lev != styler.LevelAt(currentLine))
        styler.SetLevel(currentLine, lev);

      currentLine++;
      previousLevel = currentLevel;
    }

  }

  // Fill in the real level of the next line, keeping the current flags as they will be filled in later
  styler.SetLevel(currentLine,
          previousLevel
          | (styler.LevelAt(currentLine) & ~SC_FOLDLEVELNUMBERMASK));
}