Lines 12-18
Link Here
|
12 |
|
12 |
|
13 |
import java.io.FileNotFoundException; |
13 |
import java.io.FileNotFoundException; |
14 |
import java.io.IOException; |
14 |
import java.io.IOException; |
15 |
import java.io.InputStream; |
15 |
import java.io.Reader; |
16 |
import java.util.ArrayList; |
16 |
import java.util.ArrayList; |
17 |
import java.util.LinkedList; |
17 |
import java.util.LinkedList; |
18 |
import java.util.Stack; |
18 |
import java.util.Stack; |
Lines 21-35
Link Here
|
21 |
|
21 |
|
22 |
import org.eclipse.core.resources.IFile; |
22 |
import org.eclipse.core.resources.IFile; |
23 |
import org.eclipse.photran.internal.core.lexer.FreeFormLexerPhase1; |
23 |
import org.eclipse.photran.internal.core.lexer.FreeFormLexerPhase1; |
24 |
import org.eclipse.photran.internal.core.lexer.LineInputStream; |
24 |
import org.eclipse.photran.internal.core.lexer.LineReader; |
|
|
25 |
import org.eclipse.photran.internal.core.lexer.SingleCharReader; |
25 |
|
26 |
|
26 |
/** |
27 |
/** |
27 |
* An <code>InputStream</code> that recognizes and processes Fortran INCLUDE lines. |
28 |
* An <code>Reader</code> that recognizes and processes Fortran INCLUDE lines. |
28 |
* <p> |
29 |
* <p> |
29 |
* This class implements an {@link InputStream} the provides the contents of a |
30 |
* This class implements an {@link Reader} the provides the contents of a |
30 |
* Fortran file <i>after</i> INCLUDE lines have been processed. Photran's |
31 |
* Fortran file <i>after</i> INCLUDE lines have been processed. Photran's |
31 |
* machine-constructed, free-form lexer ({@link FreeFormLexerPhase1}) tokenizes |
32 |
* machine-constructed, free-form lexer ({@link FreeFormLexerPhase1}) tokenizes |
32 |
* this InputStream, oblivious to the fact that it is actually tokenizing |
33 |
* this Reader, oblivious to the fact that it is actually tokenizing |
33 |
* preprocessed text. However, a special subclass |
34 |
* preprocessed text. However, a special subclass |
34 |
* ({@link PreprocessingFreeFormLexerPhase1}) takes care of mapping the |
35 |
* ({@link PreprocessingFreeFormLexerPhase1}) takes care of mapping the |
35 |
* preprocessed tokens back to their images and locations in the original files. |
36 |
* preprocessed tokens back to their images and locations in the original files. |
Lines 41-50
Link Here
|
41 |
* |
42 |
* |
42 |
* @author Jeff Overbey |
43 |
* @author Jeff Overbey |
43 |
*/ |
44 |
*/ |
44 |
public final class FortranPreprocessor extends InputStream |
45 |
public final class FortranPreprocessor extends SingleCharReader |
45 |
{ |
46 |
{ |
46 |
/** |
47 |
/** |
47 |
* Utility class. Originally, we simply used a <pre>Stack<LineInputStream></pre>, |
48 |
* Utility class. Originally, we simply used a <pre>Stack<LineReader></pre>, |
48 |
* but a profile revealed that Stack#peek was consuming a large amount of time |
49 |
* but a profile revealed that Stack#peek was consuming a large amount of time |
49 |
* due to repeated invocations. Now, the #topStream field in this class is |
50 |
* due to repeated invocations. Now, the #topStream field in this class is |
50 |
* accessed instead, resulting in a significant performance improvement |
51 |
* accessed instead, resulting in a significant performance improvement |
Lines 52-64
Link Here
|
52 |
*/ |
53 |
*/ |
53 |
private static final class StreamStack |
54 |
private static final class StreamStack |
54 |
{ |
55 |
{ |
55 |
private Stack<LineInputStream> streamStack = new Stack<LineInputStream>(); |
56 |
private Stack<LineReader> streamStack = new Stack<LineReader>(); |
56 |
private LineInputStream topStream = null; |
57 |
private LineReader topStream = null; |
57 |
|
58 |
|
58 |
public void push(LineInputStream lineInputStream) |
59 |
public void push(LineReader lineReader) |
59 |
{ |
60 |
{ |
60 |
streamStack.push(lineInputStream); |
61 |
streamStack.push(lineReader); |
61 |
topStream = lineInputStream; |
62 |
topStream = lineReader; |
62 |
} |
63 |
} |
63 |
|
64 |
|
64 |
public int size() |
65 |
public int size() |
Lines 93-105
Link Here
|
93 |
private ArrayList<Integer> fileStartLines; |
94 |
private ArrayList<Integer> fileStartLines; |
94 |
private ArrayList<Integer> fileStartLineAdjustments; |
95 |
private ArrayList<Integer> fileStartLineAdjustments; |
95 |
|
96 |
|
96 |
public FortranPreprocessor(InputStream readFrom, IFile file, String filename, IncludeLoaderCallback callback) throws IOException |
97 |
public FortranPreprocessor(Reader readFrom, IFile file, String filename, IncludeLoaderCallback callback) throws IOException |
97 |
{ |
98 |
{ |
98 |
this.topLevelFile = file; |
99 |
this.topLevelFile = file; |
99 |
this.callback = callback; |
100 |
this.callback = callback; |
100 |
|
101 |
|
101 |
streamStack = new StreamStack(); |
102 |
streamStack = new StreamStack(); |
102 |
streamStack.push(new LineInputStream(readFrom, filename)); |
103 |
streamStack.push(new LineReader(readFrom, filename)); |
103 |
|
104 |
|
104 |
directivesInTopLevelFile = new LinkedList<FortranIncludeDirective>(); |
105 |
directivesInTopLevelFile = new LinkedList<FortranIncludeDirective>(); |
105 |
directivesInTopLevelFile.add(null); |
106 |
directivesInTopLevelFile.add(null); |
Lines 167-175
Link Here
|
167 |
throw new IllegalArgumentException(); |
168 |
throw new IllegalArgumentException(); |
168 |
} |
169 |
} |
169 |
|
170 |
|
|
|
171 |
@Override |
170 |
public int read() throws IOException |
172 |
public int read() throws IOException |
171 |
{ |
173 |
{ |
172 |
LineInputStream currentStream = streamStack.topStream; |
174 |
LineReader currentStream = streamStack.topStream; |
173 |
if (currentStream.atBOL()) checkForInclude(); |
175 |
if (currentStream.atBOL()) checkForInclude(); |
174 |
currentStream = streamStack.topStream; |
176 |
currentStream = streamStack.topStream; |
175 |
if (currentStream.atEOF()) finishInclude(); |
177 |
if (currentStream.atEOF()) finishInclude(); |
Lines 192-202
Link Here
|
192 |
Matcher m = INCLUDE_LINE.matcher(streamStack.topStream); |
194 |
Matcher m = INCLUDE_LINE.matcher(streamStack.topStream); |
193 |
if (m.matches()) |
195 |
if (m.matches()) |
194 |
{ |
196 |
{ |
195 |
LineInputStream origStream = streamStack.topStream; |
197 |
LineReader origStream = streamStack.topStream; |
196 |
String includeLine = origStream.currentLine(); |
198 |
String includeLine = origStream.currentLine(); |
197 |
String fileToInclude = m.group(INCLUDE_LINE_CAPTURING_GROUP_OF_FILENAME); |
199 |
String fileToInclude = m.group(INCLUDE_LINE_CAPTURING_GROUP_OF_FILENAME); |
198 |
|
200 |
|
199 |
InputStream newStream = findIncludedFile(fileToInclude); |
201 |
Reader newStream = findIncludedFile(fileToInclude); |
200 |
if (newStream != null) |
202 |
if (newStream != null) |
201 |
{ |
203 |
{ |
202 |
if (inTopLevelFile()) |
204 |
if (inTopLevelFile()) |
Lines 208-214
Link Here
|
208 |
origStream.setRestartOffset(offset + includeLine.length()); |
210 |
origStream.setRestartOffset(offset + includeLine.length()); |
209 |
origStream.setRestartLine(line + 1); |
211 |
origStream.setRestartLine(line + 1); |
210 |
|
212 |
|
211 |
streamStack.push(new LineInputStream(newStream, fileToInclude, offset, line)); |
213 |
streamStack.push(new LineReader(newStream, fileToInclude, offset, line)); |
212 |
|
214 |
|
213 |
fileNames.add(fileToInclude); |
215 |
fileNames.add(fileToInclude); |
214 |
fileStartOffsets.add(new Integer(offset)); |
216 |
fileStartOffsets.add(new Integer(offset)); |
Lines 222-228
Link Here
|
222 |
} |
224 |
} |
223 |
} |
225 |
} |
224 |
|
226 |
|
225 |
protected InputStream findIncludedFile(String fileToInclude) throws IOException |
227 |
protected Reader findIncludedFile(String fileToInclude) throws IOException |
226 |
{ |
228 |
{ |
227 |
try |
229 |
try |
228 |
{ |
230 |
{ |
Lines 282-285
Link Here
|
282 |
{ |
284 |
{ |
283 |
return topLevelFile; |
285 |
return topLevelFile; |
284 |
} |
286 |
} |
|
|
287 |
|
288 |
@Override |
289 |
public void close() throws IOException |
290 |
{ |
291 |
streamStack.topStream.close(); |
292 |
} |
285 |
} |
293 |
} |