1
2
3
4
5
6
7
8
9
10 package org.syntax.jedit.tokenmarker;
11
12 import javax.swing.text.Segment;
13
14 import org.syntax.jedit.SyntaxUtilities;
15
16 /***
17 * Shell script token marker.
18 *
19 * @author Slava Pestov
20 * @version $Id: ShellScriptTokenMarker.java,v 1.18 1999/12/13 03:40:30 sp Exp $
21 */
22 public class ShellScriptTokenMarker extends TokenMarker
23 {
24
25 public static final byte LVARIABLE = Token.INTERNAL_FIRST;
26
27 public byte markTokensImpl(byte token, Segment line, int lineIndex)
28 {
29 char[] array = line.array;
30 byte cmdState = 0;
31
32 int offset = line.offset;
33 int lastOffset = offset;
34 int length = line.count + offset;
35
36 if(token == Token.LITERAL1 && lineIndex != 0
37 && lineInfo[lineIndex - 1].obj != null)
38 {
39 String str = (String)lineInfo[lineIndex - 1].obj;
40 if(str != null && str.length() == line.count
41 && SyntaxUtilities.regionMatches(false,line,
42 offset,str))
43 {
44 addToken(line.count,Token.LITERAL1);
45 return Token.NULL;
46 }
47 else
48 {
49 addToken(line.count,Token.LITERAL1);
50 lineInfo[lineIndex].obj = str;
51 return Token.LITERAL1;
52 }
53 }
54
55 boolean backslash = false;
56 loop: for(int i = offset; i < length; i++)
57 {
58 int i1 = (i+1);
59
60 char c = array[i];
61
62 if(c == '//')
63 {
64 backslash = !backslash;
65 continue;
66 }
67
68 switch(token)
69 {
70 case Token.NULL:
71 switch(c)
72 {
73 case ' ': case '\t': case '(': case ')':
74 backslash = false;
75 if(cmdState == 1
76 {
77 addToken(i - lastOffset,Token.KEYWORD1);
78 lastOffset = i;
79 cmdState = 2;
80 }
81 break;
82 case '=':
83 backslash = false;
84 if(cmdState == 1
85 {
86 addToken(i - lastOffset,token);
87 lastOffset = i;
88 cmdState = 2;
89 }
90 break;
91 case '&': case '|': case ';':
92 if(backslash)
93 backslash = false;
94 else
95 cmdState = 0;
96 break;
97 case '#':
98 if(backslash)
99 backslash = false;
100 else
101 {
102 addToken(i - lastOffset,token);
103 addToken(length - i,Token.COMMENT1);
104 lastOffset = length;
105 break loop;
106 }
107 break;
108 case '$':
109 if(backslash)
110 backslash = false;
111 else
112 {
113 addToken(i - lastOffset,token);
114 cmdState = 2;
115 lastOffset = i;
116 if(length - i >= 2)
117 {
118 switch(array[i1])
119 {
120 case '(':
121 continue;
122 case '{':
123 token = LVARIABLE;
124 break;
125 default:
126 token = Token.KEYWORD2;
127 break;
128 }
129 }
130 else
131 token = Token.KEYWORD2;
132 }
133 break;
134 case '"':
135 if(backslash)
136 backslash = false;
137 else
138 {
139 addToken(i - lastOffset,token);
140 token = Token.LITERAL1;
141 lineInfo[lineIndex].obj = null;
142 cmdState = 2;
143 lastOffset = i;
144 }
145 break;
146 case '\'':
147 if(backslash)
148 backslash = false;
149 else
150 {
151 addToken(i - lastOffset,token);
152 token = Token.LITERAL2;
153 cmdState = 2;
154 lastOffset = i;
155 }
156 break;
157 case '<':
158 if(backslash)
159 backslash = false;
160 else
161 {
162 if(length - i > 1 && array[i1] == '<')
163 {
164 addToken(i - lastOffset,
165 token);
166 token = Token.LITERAL1;
167 lastOffset = i;
168 lineInfo[lineIndex].obj =
169 new String(array,i + 2,
170 length - (i+2));
171 }
172 }
173 break;
174 default:
175 backslash = false;
176 if(Character.isLetter(c))
177 {
178 if(cmdState == 0
179 {
180 addToken(i - lastOffset,token);
181 lastOffset = i;
182 cmdState++;
183 }
184 }
185 break;
186 }
187 break;
188 case Token.KEYWORD2:
189 backslash = false;
190 if(!Character.isLetterOrDigit(c) && c != '_')
191 {
192 if(i != offset && array[i-1] == '$')
193 {
194 addToken(i1 - lastOffset,token);
195 lastOffset = i1;
196 token = Token.NULL;
197 continue;
198 }
199 else
200 {
201 addToken(i - lastOffset,token);
202 lastOffset = i;
203 token = Token.NULL;
204 }
205 }
206 break;
207 case Token.LITERAL1:
208 if(backslash)
209 backslash = false;
210 else if(c == '"')
211 {
212 addToken(i1 - lastOffset,token);
213 cmdState = 2;
214 lastOffset = i1;
215 token = Token.NULL;
216 }
217 else
218 backslash = false;
219 break;
220 case Token.LITERAL2:
221 if(backslash)
222 backslash = false;
223 else if(c == '\'')
224 {
225 addToken(i1 - lastOffset,Token.LITERAL1);
226 cmdState = 2;
227 lastOffset = i1;
228 token = Token.NULL;
229 }
230 else
231 backslash = false;
232 break;
233 case LVARIABLE:
234 backslash = false;
235 if(c == '}')
236 {
237 addToken(i1 - lastOffset,Token.KEYWORD2);
238 lastOffset = i1;
239 token = Token.NULL;
240 }
241 break;
242 default:
243 throw new InternalError("Invalid state: " + token);
244 }
245 }
246
247 switch(token)
248 {
249 case Token.NULL:
250 if(cmdState == 1)
251 addToken(length - lastOffset,Token.KEYWORD1);
252 else
253 addToken(length - lastOffset,token);
254 break;
255 case Token.LITERAL2:
256 addToken(length - lastOffset,Token.LITERAL1);
257 break;
258 case Token.KEYWORD2:
259 addToken(length - lastOffset,token);
260 token = Token.NULL;
261 break;
262 case LVARIABLE:
263 addToken(length - lastOffset,Token.INVALID);
264 token = Token.NULL;
265 break;
266 default:
267 addToken(length - lastOffset,token);
268 break;
269 }
270 return token;
271 }
272 }