001: package net.xoetrope.builder.editor.syntaxhighlight;
002:
003: /*
004: * SQLTokenMarker.java - Generic SQL token marker
005: * Copyright (C) 1999 mike dillon
006: *
007: * You may use and modify this package for any purpose. Redistribution is
008: * permitted, in both source and binary form, provided that this notice
009: * remains intact in all source distributions of this package.
010: */
011:
012: import javax.swing.text.Segment;
013:
014: /**
015: * SQL token marker.
016: *
017: * @author mike dillon
018: * @version $Id: SQLTokenMarker.java,v 1.22 2005/01/05 17:20:49 luano Exp $
019: */
020: public class SQLTokenMarker extends TokenMarker {
021: private int offset, lastOffset, lastKeyword, length;
022:
023: // public members
024: public SQLTokenMarker(KeywordMap k) {
025: this (k, false);
026: }
027:
028: public SQLTokenMarker(KeywordMap k, boolean tsql) {
029: keywords = k;
030: isTSQL = tsql;
031: }
032:
033: public byte markTokensImpl(byte token, Segment line, int lineIndex) {
034: offset = lastOffset = lastKeyword = line.offset;
035: length = line.count + offset;
036:
037: loop: for (int i = offset; i < length; i++) {
038: switch (line.array[i]) {
039: case '*':
040: if (token == Token.COMMENT1 && length - i >= 1
041: && line.array[i + 1] == '/') {
042: token = Token.NULL;
043: i++;
044: addToken((i + 1) - lastOffset, Token.COMMENT1);
045: lastOffset = i + 1;
046: } else if (token == Token.NULL) {
047: searchBack(line, i);
048: addToken(1, Token.OPERATOR);
049: lastOffset = i + 1;
050: }
051: break;
052: case '[':
053: if (token == Token.NULL) {
054: searchBack(line, i);
055: token = Token.LITERAL1;
056: literalChar = '[';
057: lastOffset = i;
058: }
059: break;
060: case ']':
061: if (token == Token.LITERAL1 && literalChar == '[') {
062: token = Token.NULL;
063: literalChar = 0;
064: addToken((i + 1) - lastOffset, Token.LITERAL1);
065: lastOffset = i + 1;
066: }
067: break;
068: case '.':
069: case ',':
070: case '(':
071: case ')':
072: if (token == Token.NULL) {
073: searchBack(line, i);
074: addToken(1, Token.NULL);
075: lastOffset = i + 1;
076: }
077: break;
078: case '+':
079: case '%':
080: case '&':
081: case '|':
082: case '^':
083: case '~':
084: case '<':
085: case '>':
086: case '=':
087: if (token == Token.NULL) {
088: searchBack(line, i);
089: addToken(1, Token.OPERATOR);
090: lastOffset = i + 1;
091: }
092: break;
093: case ' ':
094: case '\t':
095: if (token == Token.NULL) {
096: searchBack(line, i, false);
097: }
098: break;
099: case ':':
100: if (token == Token.NULL) {
101: addToken((i + 1) - lastOffset, Token.LABEL);
102: lastOffset = i + 1;
103: }
104: break;
105: case '/':
106: if (token == Token.NULL) {
107: if (length - i >= 2 && line.array[i + 1] == '*') {
108: searchBack(line, i);
109: token = Token.COMMENT1;
110: lastOffset = i;
111: i++;
112: } else {
113: searchBack(line, i);
114: addToken(1, Token.OPERATOR);
115: lastOffset = i + 1;
116: }
117: }
118: break;
119: case '-':
120: if (token == Token.NULL) {
121: if (length - i >= 2 && line.array[i + 1] == '-') {
122: searchBack(line, i);
123: addToken(length - i, Token.COMMENT1);
124: lastOffset = length;
125: break loop;
126: } else {
127: searchBack(line, i);
128: addToken(1, Token.OPERATOR);
129: lastOffset = i + 1;
130: }
131: }
132: break;
133: case '!':
134: if (isTSQL
135: && token == Token.NULL
136: && length - i >= 2
137: && (line.array[i + 1] == '='
138: || line.array[i + 1] == '<' || line.array[i + 1] == '>')) {
139: searchBack(line, i);
140: addToken(1, Token.OPERATOR);
141: lastOffset = i + 1;
142: }
143: break;
144: case '"':
145: case '\'':
146: if (token == Token.NULL) {
147: token = Token.LITERAL1;
148: literalChar = line.array[i];
149: addToken(i - lastOffset, Token.NULL);
150: lastOffset = i;
151: } else if (token == Token.LITERAL1
152: && literalChar == line.array[i]) {
153: token = Token.NULL;
154: literalChar = 0;
155: addToken((i + 1) - lastOffset, Token.LITERAL1);
156: lastOffset = i + 1;
157: }
158: break;
159: default:
160: break;
161: }
162: }
163: if (token == Token.NULL)
164: searchBack(line, length, false);
165: if (lastOffset != length)
166: addToken(length - lastOffset, token);
167: return token;
168: }
169:
170: // protected members
171: protected boolean isTSQL = false;
172:
173: // private members
174: private KeywordMap keywords;
175: private char literalChar = 0;
176:
177: private void searchBack(Segment line, int pos) {
178: searchBack(line, pos, true);
179: }
180:
181: private void searchBack(Segment line, int pos, boolean padNull) {
182: int len = pos - lastKeyword;
183: byte id = keywords.lookup(line, lastKeyword, len);
184: if (id != Token.NULL) {
185: if (lastKeyword != lastOffset)
186: addToken(lastKeyword - lastOffset, Token.NULL);
187: addToken(len, id);
188: lastOffset = pos;
189: }
190: lastKeyword = pos + 1;
191: if (padNull && lastOffset < pos)
192: addToken(pos - lastOffset, Token.NULL);
193: }
194: }
|