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 : for( int i = offset; i < length; i++ )
44  		{
45  			switch( line.array[i] )
46  			{
47  			case '*' :
48  				if( token == Token.COMMENT1 && length - i >= 1 && line.array[i + 1] == '/' )
49  				{
50  					token = Token.NULL;
51  					i++ ;
52  					addToken( ( i + 1 ) - lastOffset, Token.COMMENT1 );
53  					lastOffset = i + 1;
54  				}
55  				else if( token == Token.NULL )
56  				{
57  					searchBack( line, i );
58  					addToken( 1, Token.OPERATOR );
59  					lastOffset = i + 1;
60  				}
61  				break;
62  			case '[' :
63  				if( token == Token.NULL )
64  				{
65  					searchBack( line, i );
66  					token = Token.LITERAL1;
67  					literalChar = '[';
68  					lastOffset = i;
69  				}
70  				break;
71  			case ']' :
72  				if( token == Token.LITERAL1 && literalChar == '[' )
73  				{
74  					token = Token.NULL;
75  					literalChar = 0;
76  					addToken( ( i + 1 ) - lastOffset, Token.LITERAL1 );
77  					lastOffset = i + 1;
78  				}
79  				break;
80  			case '.' :
81  			case ',' :
82  			case '(' :
83  			case ')' :
84  				if( token == Token.NULL )
85  				{
86  					searchBack( line, i );
87  					addToken( 1, Token.NULL );
88  					lastOffset = i + 1;
89  				}
90  				break;
91  			case '+' :
92  			case '%' :
93  			case '&' :
94  			case '|' :
95  			case '^' :
96  			case '~' :
97  			case '<' :
98  			case '>' :
99  			case '=' :
100 				if( token == Token.NULL )
101 				{
102 					searchBack( line, i );
103 					addToken( 1, Token.OPERATOR );
104 					lastOffset = i + 1;
105 				}
106 				break;
107 			case ' ' :
108 			case '\t' :
109 				if( token == Token.NULL )
110 				{
111 					searchBack( line, i, false );
112 				}
113 				break;
114 			case ':' :
115 				if( token == Token.NULL )
116 				{
117 					addToken( ( i + 1 ) - lastOffset, Token.LABEL );
118 					lastOffset = i + 1;
119 				}
120 				break;
121 			case '/' :
122 				if( token == Token.NULL )
123 				{
124 					if( length - i >= 2 && line.array[i + 1] == '*' )
125 					{
126 						searchBack( line, i );
127 						token = Token.COMMENT1;
128 						lastOffset = i;
129 						i++ ;
130 					}
131 					else
132 					{
133 						searchBack( line, i );
134 						addToken( 1, Token.OPERATOR );
135 						lastOffset = i + 1;
136 					}
137 				}
138 				break;
139 			case '-' :
140 				if( token == Token.NULL )
141 				{
142 					if( length - i >= 2 && line.array[i + 1] == '-' )
143 					{
144 						searchBack( line, i );
145 						addToken( length - i, Token.COMMENT1 );
146 						lastOffset = length;
147 						break loop;
148 					}
149 					else
150 					{
151 						searchBack( line, i );
152 						addToken( 1, Token.OPERATOR );
153 						lastOffset = i + 1;
154 					}
155 				}
156 				break;
157 			case '!' :
158 				if( isTSQL && token == Token.NULL && length - i >= 2
159 						&& ( line.array[i + 1] == '=' || line.array[i + 1] == '<' || line.array[i + 1] == '>' ) )
160 				{
161 					searchBack( line, i );
162 					addToken( 1, Token.OPERATOR );
163 					lastOffset = i + 1;
164 				}
165 				break;
166 			case '"' :
167 			case '\'' :
168 				if( token == Token.NULL )
169 				{
170 					token = Token.LITERAL1;
171 					literalChar = line.array[i];
172 					addToken( i - lastOffset, Token.NULL );
173 					lastOffset = i;
174 				}
175 				else if( token == Token.LITERAL1 && literalChar == line.array[i] )
176 				{
177 					token = Token.NULL;
178 					literalChar = 0;
179 					addToken( ( i + 1 ) - lastOffset, Token.LITERAL1 );
180 					lastOffset = i + 1;
181 				}
182 				break;
183 			default :
184 				break;
185 			}
186 		}
187 		if( token == Token.NULL )
188 			searchBack( line, length, false );
189 		if( lastOffset != length )
190 			addToken( length - lastOffset, token );
191 		return token;
192 	}
193 
194 	// protected members
195 	protected boolean isTSQL = false;
196 
197 	// private members
198 	private KeywordMap keywords;
199 	private char literalChar = 0;
200 
201 	private void searchBack( Segment line, int pos )
202 	{
203 		searchBack( line, pos, true );
204 	}
205 
206 	private void searchBack( Segment line, int pos, boolean padNull )
207 	{
208 		int len = pos - lastKeyword;
209 		byte id = keywords.lookup( line, lastKeyword, len );
210 		if( id != Token.NULL )
211 		{
212 			if( lastKeyword != lastOffset )
213 				addToken( lastKeyword - lastOffset, Token.NULL );
214 			addToken( len, id );
215 			lastOffset = pos;
216 		}
217 		lastKeyword = pos + 1;
218 		if( padNull && lastOffset < pos )
219 			addToken( pos - lastOffset, Token.NULL );
220 	}
221 }