org.anarres.cpp.CppReader Maven / Gradle / Ivy
/*
* Anarres C Preprocessor
* Copyright (c) 2007-2008, Shevek
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package org.anarres.cpp;
import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import static org.anarres.cpp.Token.*;
/**
* A Reader wrapper around the Preprocessor.
*
* This is a utility class to provide a transparent {@link Reader}
* which preprocesses the input text.
*
* @see Preprocessor
* @see Reader
*/
public class CppReader extends Reader implements Closeable {
private Preprocessor cpp;
private String token;
private int idx;
public CppReader(final Reader r) {
cpp = new Preprocessor(new LexerSource(r, true) {
@Override
public String getName() {
return "";
}
});
token = "";
idx = 0;
}
public CppReader(Preprocessor p) {
cpp = p;
token = "";
idx = 0;
}
/**
* Returns the Preprocessor used by this CppReader.
*/
public Preprocessor getPreprocessor() {
return cpp;
}
/**
* Defines the given name as a macro.
*
* This is a convnience method.
*/
public void addMacro(String name)
throws LexerException {
cpp.addMacro(name);
}
/**
* Defines the given name as a macro.
*
* This is a convnience method.
*/
public void addMacro(String name, String value)
throws LexerException {
cpp.addMacro(name, value);
}
private boolean refill()
throws IOException {
try {
assert cpp != null : "cpp is null : was it closed?";
if (token == null)
return false;
while (idx >= token.length()) {
Token tok = cpp.token();
switch (tok.getType()) {
case EOF:
token = null;
return false;
case CCOMMENT:
case CPPCOMMENT:
if (!cpp.getFeature(Feature.KEEPCOMMENTS)) {
token = " ";
break;
}
default:
token = tok.getText();
break;
}
idx = 0;
}
return true;
} catch (LexerException e) {
/* Never happens.
if (e.getCause() instanceof IOException)
throw (IOException)e.getCause();
*/
IOException ie = new IOException(String.valueOf(e));
ie.initCause(e);
throw ie;
}
}
@Override
public int read()
throws IOException {
if (!refill())
return -1;
return token.charAt(idx++);
}
/* XXX Very slow and inefficient. */
public int read(char cbuf[], int off, int len)
throws IOException {
if (token == null)
return -1;
for (int i = 0; i < len; i++) {
int ch = read();
if (ch == -1)
return i;
cbuf[off + i] = (char) ch;
}
return len;
}
@Override
public void close()
throws IOException {
if (cpp != null) {
cpp.close();
cpp = null;
}
token = null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy