Logo Search packages:      
Sourcecode: wxwindows2.4 version File versions

LexCrontab.cxx

Go to the documentation of this file.
// Scintilla source code edit control
/** @file LexCrontab.cxx
 ** Lexer to use with extended crontab files used by a powerful
 ** Windows scheduler/event monitor/automation manager nnCron.
 ** (http://nemtsev.eserv.ru/)
 **/
// Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordList
*keywordLists[], Accessor &styler)
{
      int state = SCE_NNCRONTAB_DEFAULT;
      char chNext = styler[startPos];
      int lengthDoc = startPos + length;
      // create a buffer large enough to take the largest chunk...
      char *buffer = new char[length];
      int bufferCount = 0;
      // used when highliting environment variables inside quoted string:
      bool insideString = false;

      // this assumes that we have 3 keyword list in conf.properties
      WordList &section = *keywordLists[0];
      WordList &keyword = *keywordLists[1];
      WordList &modifier = *keywordLists[2];

      // go through all provided text segment
      // using the hand-written state machine shown below
      styler.StartAt(startPos);
      styler.StartSegment(startPos);
      for (int i = startPos; i < lengthDoc; i++) {
            char ch = chNext;
            chNext = styler.SafeGetCharAt(i + 1);

            if (styler.IsLeadByte(ch)) {
                  chNext = styler.SafeGetCharAt(i + 2);
                  i++;
                  continue;
            }
            switch(state) {
                  case SCE_NNCRONTAB_DEFAULT:
                        if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
                              // whitespace is simply ignored here...
                              styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
                              break;
                        } else if( ch == '#' && styler.SafeGetCharAt(i+1) == '(') {
                              // signals the start of a task...
                              state = SCE_NNCRONTAB_TASK;
                              styler.ColourTo(i,SCE_NNCRONTAB_TASK);
                        }
                          else if( ch == '\\' && (styler.SafeGetCharAt(i+1) == ' ' ||
                                                             styler.SafeGetCharAt(i+1) == '\t')) {
                              // signals the start of an extended comment...
                              state = SCE_NNCRONTAB_COMMENT;
                              styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
                        } else if( ch == '#' ) {
                              // signals the start of a plain comment...
                              state = SCE_NNCRONTAB_COMMENT;
                              styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
                        } else if( ch == ')' && styler.SafeGetCharAt(i+1) == '#') {
                              // signals the end of a task...
                              state = SCE_NNCRONTAB_TASK;
                              styler.ColourTo(i,SCE_NNCRONTAB_TASK);
                        } else if( ch == '"') {
                              state = SCE_NNCRONTAB_STRING;
                              styler.ColourTo(i,SCE_NNCRONTAB_STRING);
                        } else if( ch == '%') {
                              // signals environment variables
                              state = SCE_NNCRONTAB_ENVIRONMENT;
                              styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
                        } else if( ch == '<' && styler.SafeGetCharAt(i+1) == '%') {
                              // signals environment variables
                              state = SCE_NNCRONTAB_ENVIRONMENT;
                              styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
                        } else if( ch == '*' ) {
                              // signals an asterisk
                              // no state jump necessary for this simple case...
                              styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
                        } else if( isalpha(ch) || ch == '<' ) {
                              // signals the start of an identifier
                              bufferCount = 0;
                              buffer[bufferCount++] = ch;
                              state = SCE_NNCRONTAB_IDENTIFIER;
                        } else if( isdigit(ch) ) {
                              // signals the start of a number
                              bufferCount = 0;
                              buffer[bufferCount++] = ch;
                              state = SCE_NNCRONTAB_NUMBER;
                        } else {
                              // style it the default style..
                              styler.ColourTo(i,SCE_NNCRONTAB_DEFAULT);
                        }
                        break;

                  case SCE_NNCRONTAB_COMMENT:
                        // if we find a newline here,
                        // we simply go to default state
                        // else continue to work on it...
                        if( ch == '\n' || ch == '\r' ) {
                              state = SCE_NNCRONTAB_DEFAULT;
                        } else {
                              styler.ColourTo(i,SCE_NNCRONTAB_COMMENT);
                        }
                        break;

                  case SCE_NNCRONTAB_TASK:
                        // if we find a newline here,
                        // we simply go to default state
                        // else continue to work on it...
                        if( ch == '\n' || ch == '\r' ) {
                              state = SCE_NNCRONTAB_DEFAULT;
                        } else {
                              styler.ColourTo(i,SCE_NNCRONTAB_TASK);
                        }
                        break;

                  case SCE_NNCRONTAB_STRING:
                        if( ch == '%' ) {
                              state = SCE_NNCRONTAB_ENVIRONMENT;
                              insideString = true;
                              styler.ColourTo(i-1,SCE_NNCRONTAB_STRING);
                              break;
                        }
                        // if we find the end of a string char, we simply go to default state
                        // else we're still dealing with an string...
                        if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') ||
                              (ch == '\n') || (ch == '\r') ) {
                              state = SCE_NNCRONTAB_DEFAULT;
                        }
                        styler.ColourTo(i,SCE_NNCRONTAB_STRING);
                        break;

                  case SCE_NNCRONTAB_ENVIRONMENT:
                        // if we find the end of a string char, we simply go to default state
                        // else we're still dealing with an string...
                        if( ch == '%' && insideString ) {
                              state = SCE_NNCRONTAB_STRING;
                              insideString = false;
                              break;
                        }
                        if( (ch == '%' && styler.SafeGetCharAt(i-1)!='\\')
                              || (ch == '\n') || (ch == '\r') || (ch == '>') ) {
                              state = SCE_NNCRONTAB_DEFAULT;
                              styler.ColourTo(i,SCE_NNCRONTAB_ENVIRONMENT);
                              break;
                        }
                        styler.ColourTo(i+1,SCE_NNCRONTAB_ENVIRONMENT);
                        break;

                  case SCE_NNCRONTAB_IDENTIFIER:
                        // stay  in CONF_IDENTIFIER state until we find a non-alphanumeric
                        if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') ||
                              (ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
                              (ch == '@') ) {
                              buffer[bufferCount++] = ch;
                        } else {
                              state = SCE_NNCRONTAB_DEFAULT;
                              buffer[bufferCount] = '\0';

                              // check if the buffer contains a keyword,
                              // and highlight it if it is a keyword...
                              if(section.InList(buffer)) {
                                    styler.ColourTo(i,SCE_NNCRONTAB_SECTION );
                              } else if(keyword.InList(buffer)) {
                                    styler.ColourTo(i-1,SCE_NNCRONTAB_KEYWORD );
                              } // else if(strchr(buffer,'/') || strchr(buffer,'.')) {
                              //    styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);
                              // }
                                else if(modifier.InList(buffer)) {
                                    styler.ColourTo(i-1,SCE_NNCRONTAB_MODIFIER );
                                }   else {
                                    styler.ColourTo(i-1,SCE_NNCRONTAB_DEFAULT);
                              }
                              // push back the faulty character
                              chNext = styler[i--];
                        }
                        break;

                  case SCE_NNCRONTAB_NUMBER:
                        // stay  in CONF_NUMBER state until we find a non-numeric
                        if( isdigit(ch) /* || ch == '.' */ ) {
                              buffer[bufferCount++] = ch;
                        } else {
                              state = SCE_NNCRONTAB_DEFAULT;
                              buffer[bufferCount] = '\0';
                              // Colourize here... (normal number)
                              styler.ColourTo(i-1,SCE_NNCRONTAB_NUMBER);
                              // push back a character
                              chNext = styler[i--];
                        }
                        break;
            }
      }
      delete []buffer;
}

static const char * const cronWordListDesc[] = {
      "Section keywords and Forth words",
      "nnCrontab keywords",
      "Modifiers",
      0
};

LexerModule lmNncrontab(SCLEX_NNCRONTAB, ColouriseNncrontabDoc, "nncrontab", 0, cronWordListDesc);

Generated by  Doxygen 1.6.0   Back to index