View Javadoc

1   /*
2    * SQLTokenMarker.java - Generic SQL token marker
3    * Copyright (C) 1999 mike dillon
4    *
5    * You may use and modify this package for any purpose. Redistribution is
6    * permitted, in both source and binary form, provided that this notice
7    * remains intact in all source distributions of this package.
8    */
9   
10  package org.syntax.jedit.tokenmarker;
11  
12  import javax.swing.text.Segment;
13  
14  import org.syntax.jedit.KeywordMap;
15  
16  /***
17   * SQL token marker.
18   *
19   * @author mike dillon
20   * @version $Id: SQLTokenMarker.java,v 1.6 1999/04/19 05:38:20 sp Exp $
21   */
22  public class SQLTokenMarker extends TokenMarker
23  {
24  	private int offset, lastOffset, lastKeyword, length;
25  
26  	// public members
27  	public SQLTokenMarker(KeywordMap k)
28  	{
29  		this(k, false);
30  	}
31  
32  	public SQLTokenMarker(KeywordMap k, boolean tsql)
33  	{
34  		keywords = k;
35  		isTSQL = tsql;
36  	}
37  
38  	public byte markTokensImpl(byte token, Segment line, int lineIndex)
39  	{
40  		offset = lastOffset = lastKeyword = line.offset;
41  		length = line.count + offset;
42  
43  loop:
44  		for(int i = offset; i < length; i++)
45  		{
46  			switch(line.array[i])
47  			{
48  			case '*':
49  				if(token == Token.COMMENT1 && length - i >= 1 && line.array[i+1] == '/')
50  				{
51  					token = Token.NULL;
52  					i++;
53  					addToken((i + 1) - lastOffset,Token.COMMENT1);
54  					lastOffset = i + 1;
55  				}
56  				else if (token == Token.NULL)
57  				{
58  					searchBack(line, i);
59  					addToken(1,Token.OPERATOR);
60  					lastOffset = i + 1;
61  				}
62  				break;
63  			case '[':
64  				if(token == Token.NULL)
65  				{
66  					searchBack(line, i);
67  					token = Token.LITERAL1;
68  					literalChar = '[';
69  					lastOffset = i;
70  				}
71  				break;
72  			case ']':
73  				if(token == Token.LITERAL1 && literalChar == '[')
74  				{
75  					token = Token.NULL;
76  					literalChar = 0;
77  					addToken((i + 1) - lastOffset,Token.LITERAL1);
78  					lastOffset = i + 1;
79  				}
80  				break;
81  			case '.': case ',': case '(': case ')':
82  				if (token == Token.NULL) {
83  					searchBack(line, i);
84  					addToken(1, Token.NULL);
85  					lastOffset = i + 1;
86  				}
87  				break;
88  			case '+': case '%': case '&': case '|': case '^':
89  			case '~': case '<': case '>': case '=':
90  				if (token == Token.NULL) {
91  					searchBack(line, i);
92  					addToken(1,Token.OPERATOR);
93  					lastOffset = i + 1;
94  				}
95  				break;
96  			case ' ': case '\t':
97  				if (token == Token.NULL) {
98  					searchBack(line, i, false);
99  				}
100 				break;
101 			case ':':
102 				if(token == Token.NULL)
103 				{
104 					addToken((i+1) - lastOffset,Token.LABEL);
105 					lastOffset = i + 1;
106 				}
107 				break;
108 			case '/':
109 				if(token == Token.NULL)
110 				{
111 					if (length - i >= 2 && line.array[i + 1] == '*')
112 					{
113 						searchBack(line, i);
114 						token = Token.COMMENT1;
115 						lastOffset = i;
116 						i++;
117 					}
118 					else
119 					{
120 						searchBack(line, i);
121 						addToken(1,Token.OPERATOR);
122 						lastOffset = i + 1;
123 					}
124 				}
125 				break;
126 			case '-':
127 				if(token == Token.NULL)
128 				{
129 					if (length - i >= 2 && line.array[i+1] == '-')
130 					{
131 						searchBack(line, i);
132 						addToken(length - i,Token.COMMENT1);
133 						lastOffset = length;
134 						break loop;
135 					}
136 					else
137 					{
138 						searchBack(line, i);
139 						addToken(1,Token.OPERATOR);
140 						lastOffset = i + 1;
141 					}
142 				}
143 				break;
144 			case '!':
145 				if(isTSQL && token == Token.NULL && length - i >= 2 &&
146 				(line.array[i+1] == '=' || line.array[i+1] == '<' || line.array[i+1] == '>'))
147 				{
148 					searchBack(line, i);
149 					addToken(1,Token.OPERATOR);
150 					lastOffset = i + 1;
151 				}
152 				break;
153 			case '"': case '\'':
154 				if(token == Token.NULL)
155 				{
156 					token = Token.LITERAL1;
157 					literalChar = line.array[i];
158 					addToken(i - lastOffset,Token.NULL);
159 					lastOffset = i;
160 				}
161 				else if(token == Token.LITERAL1 && literalChar == line.array[i])
162 				{
163 					token = Token.NULL;
164 					literalChar = 0;
165 					addToken((i + 1) - lastOffset,Token.LITERAL1);
166 					lastOffset = i + 1;
167 				}
168 				break;
169 			default:
170 				break;
171 			}
172 		}
173 		if(token == Token.NULL)
174 			searchBack(line, length, false);
175 		if(lastOffset != length)
176 			addToken(length - lastOffset,token);
177 		return token;
178 	}
179 
180 	// protected members
181 	protected boolean isTSQL = false;
182 
183 	// private members
184 	private KeywordMap keywords;
185 	private char literalChar = 0;
186 
187 	private void searchBack(Segment line, int pos)
188 	{
189 		searchBack(line, pos, true);
190 	}
191 
192 	private void searchBack(Segment line, int pos, boolean padNull)
193 	{
194 		int len = pos - lastKeyword;
195 		byte id = keywords.lookup(line,lastKeyword,len);
196 		if(id != Token.NULL)
197 		{
198 			if(lastKeyword != lastOffset)
199 				addToken(lastKeyword - lastOffset,Token.NULL);
200 			addToken(len,id);
201 			lastOffset = pos;
202 		}
203 		lastKeyword = pos + 1;
204 		if (padNull && lastOffset < pos)
205 			addToken(pos - lastOffset, Token.NULL);
206 	}
207 }