1 // Scintilla source code edit control
2 /** @file LexCrontab.cxx
3 ** Lexer to use with extended crontab files used by a powerful
4 ** Windows scheduler/event monitor/automation manager nnCron.
5 ** (http://nemtsev.eserv.ru/)
7 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
8 // The License.txt file describes the conditions under which this software may be distributed.
21 #include "Scintilla.h"
24 static void ColouriseNncrontabDoc(unsigned int startPos
, int length
, int, WordList
25 *keywordLists
[], Accessor
&styler
)
27 int state
= SCE_NNCRONTAB_DEFAULT
;
28 char chNext
= styler
[startPos
];
29 int lengthDoc
= startPos
+ length
;
30 // create a buffer large enough to take the largest chunk...
31 char *buffer
= new char[length
];
33 // used when highliting environment variables inside quoted string:
34 bool insideString
= false;
36 // this assumes that we have 3 keyword list in conf.properties
37 WordList
§ion
= *keywordLists
[0];
38 WordList
&keyword
= *keywordLists
[1];
39 WordList
&modifier
= *keywordLists
[2];
41 // go through all provided text segment
42 // using the hand-written state machine shown below
43 styler
.StartAt(startPos
);
44 styler
.StartSegment(startPos
);
45 for (int i
= startPos
; i
< lengthDoc
; i
++) {
47 chNext
= styler
.SafeGetCharAt(i
+ 1);
49 if (styler
.IsLeadByte(ch
)) {
50 chNext
= styler
.SafeGetCharAt(i
+ 2);
55 case SCE_NNCRONTAB_DEFAULT
:
56 if( ch
== '\n' || ch
== '\r' || ch
== '\t' || ch
== ' ') {
57 // whitespace is simply ignored here...
58 styler
.ColourTo(i
,SCE_NNCRONTAB_DEFAULT
);
60 } else if( ch
== '#' && styler
.SafeGetCharAt(i
+1) == '(') {
61 // signals the start of a task...
62 state
= SCE_NNCRONTAB_TASK
;
63 styler
.ColourTo(i
,SCE_NNCRONTAB_TASK
);
65 else if( ch
== '\\' && (styler
.SafeGetCharAt(i
+1) == ' ' ||
66 styler
.SafeGetCharAt(i
+1) == '\t')) {
67 // signals the start of an extended comment...
68 state
= SCE_NNCRONTAB_COMMENT
;
69 styler
.ColourTo(i
,SCE_NNCRONTAB_COMMENT
);
70 } else if( ch
== '#' ) {
71 // signals the start of a plain comment...
72 state
= SCE_NNCRONTAB_COMMENT
;
73 styler
.ColourTo(i
,SCE_NNCRONTAB_COMMENT
);
74 } else if( ch
== ')' && styler
.SafeGetCharAt(i
+1) == '#') {
75 // signals the end of a task...
76 state
= SCE_NNCRONTAB_TASK
;
77 styler
.ColourTo(i
,SCE_NNCRONTAB_TASK
);
78 } else if( ch
== '"') {
79 state
= SCE_NNCRONTAB_STRING
;
80 styler
.ColourTo(i
,SCE_NNCRONTAB_STRING
);
81 } else if( ch
== '%') {
82 // signals environment variables
83 state
= SCE_NNCRONTAB_ENVIRONMENT
;
84 styler
.ColourTo(i
,SCE_NNCRONTAB_ENVIRONMENT
);
85 } else if( ch
== '<' && styler
.SafeGetCharAt(i
+1) == '%') {
86 // signals environment variables
87 state
= SCE_NNCRONTAB_ENVIRONMENT
;
88 styler
.ColourTo(i
,SCE_NNCRONTAB_ENVIRONMENT
);
89 } else if( ch
== '*' ) {
90 // signals an asterisk
91 // no state jump necessary for this simple case...
92 styler
.ColourTo(i
,SCE_NNCRONTAB_ASTERISK
);
93 } else if( isalpha(ch
) || ch
== '<' ) {
94 // signals the start of an identifier
96 buffer
[bufferCount
++] = ch
;
97 state
= SCE_NNCRONTAB_IDENTIFIER
;
98 } else if( isdigit(ch
) ) {
99 // signals the start of a number
101 buffer
[bufferCount
++] = ch
;
102 state
= SCE_NNCRONTAB_NUMBER
;
104 // style it the default style..
105 styler
.ColourTo(i
,SCE_NNCRONTAB_DEFAULT
);
109 case SCE_NNCRONTAB_COMMENT
:
110 // if we find a newline here,
111 // we simply go to default state
112 // else continue to work on it...
113 if( ch
== '\n' || ch
== '\r' ) {
114 state
= SCE_NNCRONTAB_DEFAULT
;
116 styler
.ColourTo(i
,SCE_NNCRONTAB_COMMENT
);
120 case SCE_NNCRONTAB_TASK
:
121 // if we find a newline here,
122 // we simply go to default state
123 // else continue to work on it...
124 if( ch
== '\n' || ch
== '\r' ) {
125 state
= SCE_NNCRONTAB_DEFAULT
;
127 styler
.ColourTo(i
,SCE_NNCRONTAB_TASK
);
131 case SCE_NNCRONTAB_STRING
:
133 state
= SCE_NNCRONTAB_ENVIRONMENT
;
135 styler
.ColourTo(i
-1,SCE_NNCRONTAB_STRING
);
138 // if we find the end of a string char, we simply go to default state
139 // else we're still dealing with an string...
140 if( (ch
== '"' && styler
.SafeGetCharAt(i
-1)!='\\') ||
141 (ch
== '\n') || (ch
== '\r') ) {
142 state
= SCE_NNCRONTAB_DEFAULT
;
144 styler
.ColourTo(i
,SCE_NNCRONTAB_STRING
);
147 case SCE_NNCRONTAB_ENVIRONMENT
:
148 // if we find the end of a string char, we simply go to default state
149 // else we're still dealing with an string...
150 if( ch
== '%' && insideString
) {
151 state
= SCE_NNCRONTAB_STRING
;
152 insideString
= false;
155 if( (ch
== '%' && styler
.SafeGetCharAt(i
-1)!='\\')
156 || (ch
== '\n') || (ch
== '\r') || (ch
== '>') ) {
157 state
= SCE_NNCRONTAB_DEFAULT
;
158 styler
.ColourTo(i
,SCE_NNCRONTAB_ENVIRONMENT
);
161 styler
.ColourTo(i
+1,SCE_NNCRONTAB_ENVIRONMENT
);
164 case SCE_NNCRONTAB_IDENTIFIER
:
165 // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
166 if( isalnum(ch
) || (ch
== '_') || (ch
== '-') || (ch
== '/') ||
167 (ch
== '$') || (ch
== '.') || (ch
== '<') || (ch
== '>') ||
169 buffer
[bufferCount
++] = ch
;
171 state
= SCE_NNCRONTAB_DEFAULT
;
172 buffer
[bufferCount
] = '\0';
174 // check if the buffer contains a keyword,
175 // and highlight it if it is a keyword...
176 if(section
.InList(buffer
)) {
177 styler
.ColourTo(i
,SCE_NNCRONTAB_SECTION
);
178 } else if(keyword
.InList(buffer
)) {
179 styler
.ColourTo(i
-1,SCE_NNCRONTAB_KEYWORD
);
180 } // else if(strchr(buffer,'/') || strchr(buffer,'.')) {
181 // styler.ColourTo(i-1,SCE_NNCRONTAB_EXTENSION);
183 else if(modifier
.InList(buffer
)) {
184 styler
.ColourTo(i
-1,SCE_NNCRONTAB_MODIFIER
);
186 styler
.ColourTo(i
-1,SCE_NNCRONTAB_DEFAULT
);
188 // push back the faulty character
189 chNext
= styler
[i
--];
193 case SCE_NNCRONTAB_NUMBER
:
194 // stay in CONF_NUMBER state until we find a non-numeric
195 if( isdigit(ch
) /* || ch == '.' */ ) {
196 buffer
[bufferCount
++] = ch
;
198 state
= SCE_NNCRONTAB_DEFAULT
;
199 buffer
[bufferCount
] = '\0';
200 // Colourize here... (normal number)
201 styler
.ColourTo(i
-1,SCE_NNCRONTAB_NUMBER
);
202 // push back a character
203 chNext
= styler
[i
--];
211 LexerModule
lmNncrontab(SCLEX_NNCRONTAB
, ColouriseNncrontabDoc
, "nncrontab");