]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/stc/scintilla/src/LexConf.cxx
Updated wxSTC's copy of Scintilla to version 1.61
[wxWidgets.git] / contrib / src / stc / scintilla / src / LexConf.cxx
1 // Scintilla source code edit control
2 /** @file LexConf.cxx
3 ** Lexer for Apache Configuration Files.
4 **
5 ** First working version contributed by Ahmad Zawawi <zeus_go64@hotmail.com> on October 28, 2000.
6 ** i created this lexer because i needed something pretty when dealing
7 ** when Apache Configuration files...
8 **/
9 // Copyright 1998-2001 by Neil Hodgson <neilh@scintilla.org>
10 // The License.txt file describes the conditions under which this software may be distributed.
11
12 #include <stdlib.h>
13 #include <string.h>
14 #include <ctype.h>
15 #include <stdio.h>
16 #include <stdarg.h>
17
18 #include "Platform.h"
19
20 #include "PropSet.h"
21 #include "Accessor.h"
22 #include "KeyWords.h"
23 #include "Scintilla.h"
24 #include "SciLexer.h"
25
26 static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor &styler)
27 {
28 int state = SCE_CONF_DEFAULT;
29 char chNext = styler[startPos];
30 int lengthDoc = startPos + length;
31 // create a buffer large enough to take the largest chunk...
32 char *buffer = new char[length];
33 int bufferCount = 0;
34
35 // this assumes that we have 2 keyword list in conf.properties
36 WordList &directives = *keywordLists[0];
37 WordList &params = *keywordLists[1];
38
39 // go through all provided text segment
40 // using the hand-written state machine shown below
41 styler.StartAt(startPos);
42 styler.StartSegment(startPos);
43 for (int i = startPos; i < lengthDoc; i++) {
44 char ch = chNext;
45 chNext = styler.SafeGetCharAt(i + 1);
46
47 if (styler.IsLeadByte(ch)) {
48 chNext = styler.SafeGetCharAt(i + 2);
49 i++;
50 continue;
51 }
52 switch(state) {
53 case SCE_CONF_DEFAULT:
54 if( ch == '\n' || ch == '\r' || ch == '\t' || ch == ' ') {
55 // whitespace is simply ignored here...
56 styler.ColourTo(i,SCE_CONF_DEFAULT);
57 break;
58 } else if( ch == '#' ) {
59 // signals the start of a comment...
60 state = SCE_CONF_COMMENT;
61 styler.ColourTo(i,SCE_CONF_COMMENT);
62 } else if( ch == '.' /*|| ch == '/'*/) {
63 // signals the start of a file...
64 state = SCE_CONF_EXTENSION;
65 styler.ColourTo(i,SCE_CONF_EXTENSION);
66 } else if( ch == '"') {
67 state = SCE_CONF_STRING;
68 styler.ColourTo(i,SCE_CONF_STRING);
69 } else if( ispunct(ch) ) {
70 // signals an operator...
71 // no state jump necessary for this
72 // simple case...
73 styler.ColourTo(i,SCE_CONF_OPERATOR);
74 } else if( isalpha(ch) ) {
75 // signals the start of an identifier
76 bufferCount = 0;
77 buffer[bufferCount++] = static_cast<char>(tolower(ch));
78 state = SCE_CONF_IDENTIFIER;
79 } else if( isdigit(ch) ) {
80 // signals the start of a number
81 bufferCount = 0;
82 buffer[bufferCount++] = ch;
83 //styler.ColourTo(i,SCE_CONF_NUMBER);
84 state = SCE_CONF_NUMBER;
85 } else {
86 // style it the default style..
87 styler.ColourTo(i,SCE_CONF_DEFAULT);
88 }
89 break;
90
91 case SCE_CONF_COMMENT:
92 // if we find a newline here,
93 // we simply go to default state
94 // else continue to work on it...
95 if( ch == '\n' || ch == '\r' ) {
96 state = SCE_CONF_DEFAULT;
97 } else {
98 styler.ColourTo(i,SCE_CONF_COMMENT);
99 }
100 break;
101
102 case SCE_CONF_EXTENSION:
103 // if we find a non-alphanumeric char,
104 // we simply go to default state
105 // else we're still dealing with an extension...
106 if( isalnum(ch) || (ch == '_') ||
107 (ch == '-') || (ch == '$') ||
108 (ch == '/') || (ch == '.') || (ch == '*') )
109 {
110 styler.ColourTo(i,SCE_CONF_EXTENSION);
111 } else {
112 state = SCE_CONF_DEFAULT;
113 chNext = styler[i--];
114 }
115 break;
116
117 case SCE_CONF_STRING:
118 // if we find the end of a string char, we simply go to default state
119 // else we're still dealing with an string...
120 if( (ch == '"' && styler.SafeGetCharAt(i-1)!='\\') || (ch == '\n') || (ch == '\r') ) {
121 state = SCE_CONF_DEFAULT;
122 }
123 styler.ColourTo(i,SCE_CONF_STRING);
124 break;
125
126 case SCE_CONF_IDENTIFIER:
127 // stay in CONF_IDENTIFIER state until we find a non-alphanumeric
128 if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
129 buffer[bufferCount++] = static_cast<char>(tolower(ch));
130 } else {
131 state = SCE_CONF_DEFAULT;
132 buffer[bufferCount] = '\0';
133
134 // check if the buffer contains a keyword, and highlight it if it is a keyword...
135 if(directives.InList(buffer)) {
136 styler.ColourTo(i-1,SCE_CONF_DIRECTIVE );
137 } else if(params.InList(buffer)) {
138 styler.ColourTo(i-1,SCE_CONF_PARAMETER );
139 } else if(strchr(buffer,'/') || strchr(buffer,'.')) {
140 styler.ColourTo(i-1,SCE_CONF_EXTENSION);
141 } else {
142 styler.ColourTo(i-1,SCE_CONF_DEFAULT);
143 }
144
145 // push back the faulty character
146 chNext = styler[i--];
147
148 }
149 break;
150
151 case SCE_CONF_NUMBER:
152 // stay in CONF_NUMBER state until we find a non-numeric
153 if( isdigit(ch) || ch == '.') {
154 buffer[bufferCount++] = ch;
155 } else {
156 state = SCE_CONF_DEFAULT;
157 buffer[bufferCount] = '\0';
158
159 // Colourize here...
160 if( strchr(buffer,'.') ) {
161 // it is an IP address...
162 styler.ColourTo(i-1,SCE_CONF_IP);
163 } else {
164 // normal number
165 styler.ColourTo(i-1,SCE_CONF_NUMBER);
166 }
167
168 // push back a character
169 chNext = styler[i--];
170 }
171 break;
172
173 }
174 }
175 delete []buffer;
176 }
177
178 static const char * const confWordListDesc[] = {
179 "Directives",
180 "Parameters",
181 0
182 };
183
184 LexerModule lmConf(SCLEX_CONF, ColouriseConfDoc, "conf", 0, confWordListDesc);