001: /**
002: *
003: * Copyright 2005 Jeremy Rayner
004: *
005: * Licensed under the Apache License, Version 2.0 (the "License");
006: * you may not use this file except in compliance with the License.
007: * You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: **/package org.codehaus.groovy.antlr;
018:
019: import java.util.List;
020: import java.util.ArrayList;
021:
022: /**
023: * A simple buffer that provides line/col access to chunks of source code
024: * held within itself.
025: *
026: * @author <a href="mailto:groovy@ross-rayner.com">Jeremy Rayner</a>
027: * @version $Revision: 2250 $
028: */
029: public class SourceBuffer {
030: private List lines;
031: private StringBuffer current;
032:
033: public SourceBuffer() {
034: lines = new ArrayList();
035: //lines.add(new StringBuffer()); // dummy row for position [0] in the List
036:
037: current = new StringBuffer();
038: lines.add(current);
039: }
040:
041: /**
042: * Obtains a snippet of the source code within the bounds specified
043: * @param start (inclusive line/ inclusive column)
044: * @param end (inclusive line / exclusive column)
045: * @return specified snippet of source code as a String, or null if no source available
046: */
047: public String getSnippet(LineColumn start, LineColumn end) {
048: // preconditions
049: if (start == null || end == null) {
050: return null;
051: } // no text to return
052: if (start.equals(end)) {
053: return null;
054: } // no text to return
055: if (lines.size() == 1 && current.length() == 0) {
056: return null;
057: } // buffer hasn't been filled yet
058:
059: // working variables
060: int startLine = start.getLine();
061: int startColumn = start.getColumn();
062: int endLine = end.getLine();
063: int endColumn = end.getColumn();
064:
065: // reset any out of bounds requests
066: if (startLine < 1) {
067: startLine = 1;
068: }
069: if (endLine < 1) {
070: endLine = 1;
071: }
072: if (startColumn < 1) {
073: startColumn = 1;
074: }
075: if (endColumn < 1) {
076: endColumn = 1;
077: }
078: if (startLine > lines.size()) {
079: startLine = lines.size();
080: }
081: if (endLine > lines.size()) {
082: endLine = lines.size();
083: }
084:
085: // obtain the snippet from the buffer within specified bounds
086: StringBuffer snippet = new StringBuffer();
087: for (int i = startLine - 1; i < endLine; i++) {
088: String line = ((StringBuffer) lines.get(i)).toString();
089: if (startLine == endLine) {
090: // reset any out of bounds requests (again)
091: if (startColumn > line.length()) {
092: startColumn = line.length();
093: }
094: if (startColumn < 1) {
095: startColumn = 1;
096: }
097: if (endColumn > line.length()) {
098: endColumn = line.length() + 1;
099: }
100: if (endColumn < 1) {
101: endColumn = 1;
102: }
103:
104: line = line.substring(startColumn - 1, endColumn - 1);
105: } else {
106: if (i == startLine - 1) {
107: if (startColumn - 1 < line.length()) {
108: line = line.substring(startColumn - 1);
109: }
110: }
111: if (i == endLine - 1) {
112: if (endColumn - 1 < line.length()) {
113: line = line.substring(0, endColumn - 1);
114: }
115: }
116: }
117: snippet.append(line);
118: }
119: return snippet.toString();
120: }
121:
122: /**
123: * Writes the specified character into the buffer
124: * @param c
125: */
126: public void write(int c) {
127: if (c != -1) {
128: current.append((char) c);
129: }
130: if (c == '\n') {
131: current = new StringBuffer();
132: lines.add(current);
133: }
134: }
135: }
|