aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/org
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2015-03-23 22:20:11 +0100
committerSven Gothel <[email protected]>2015-03-23 22:20:11 +0100
commit0bb7cf5586f08c00de051036427de36e2b1601f4 (patch)
tree52e807d3c452d619a942379e3ef8768a2407b020 /src/main/java/org
parente3b1d17a2f2b4070c1080fa6f78cfc1bcd28c78c (diff)
Relocate JCPP package: org/anarres/cpp -> com/jogamp/gluegen/jcpp
Diffstat (limited to 'src/main/java/org')
-rw-r--r--src/main/java/org/anarres/cpp/Argument.java75
-rw-r--r--src/main/java/org/anarres/cpp/BuildMetadata.java72
-rw-r--r--src/main/java/org/anarres/cpp/ChrootFileSystem.java84
-rw-r--r--src/main/java/org/anarres/cpp/CppReader.java147
-rw-r--r--src/main/java/org/anarres/cpp/CppTask.java215
-rw-r--r--src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java98
-rw-r--r--src/main/java/org/anarres/cpp/Feature.java42
-rw-r--r--src/main/java/org/anarres/cpp/FileLexerSource.java89
-rw-r--r--src/main/java/org/anarres/cpp/FixedTokenSource.java59
-rw-r--r--src/main/java/org/anarres/cpp/InputLexerSource.java64
-rw-r--r--src/main/java/org/anarres/cpp/InternalException.java31
-rw-r--r--src/main/java/org/anarres/cpp/JavaFileSystem.java84
-rw-r--r--src/main/java/org/anarres/cpp/JoinReader.java218
-rw-r--r--src/main/java/org/anarres/cpp/LexerException.java33
-rw-r--r--src/main/java/org/anarres/cpp/LexerSource.java985
-rw-r--r--src/main/java/org/anarres/cpp/Macro.java190
-rw-r--r--src/main/java/org/anarres/cpp/MacroTokenSource.java207
-rw-r--r--src/main/java/org/anarres/cpp/Main.java195
-rw-r--r--src/main/java/org/anarres/cpp/NumericValue.java215
-rw-r--r--src/main/java/org/anarres/cpp/Preprocessor.java2154
-rw-r--r--src/main/java/org/anarres/cpp/PreprocessorCommand.java44
-rw-r--r--src/main/java/org/anarres/cpp/PreprocessorListener.java59
-rw-r--r--src/main/java/org/anarres/cpp/ResourceFileSystem.java81
-rw-r--r--src/main/java/org/anarres/cpp/Source.java296
-rw-r--r--src/main/java/org/anarres/cpp/SourceIterator.java87
-rw-r--r--src/main/java/org/anarres/cpp/State.java68
-rw-r--r--src/main/java/org/anarres/cpp/StringLexerSource.java53
-rw-r--r--src/main/java/org/anarres/cpp/Token.java193
-rw-r--r--src/main/java/org/anarres/cpp/TokenSnifferSource.java45
-rw-r--r--src/main/java/org/anarres/cpp/TokenType.java128
-rw-r--r--src/main/java/org/anarres/cpp/VirtualFile.java45
-rw-r--r--src/main/java/org/anarres/cpp/VirtualFileSystem.java31
-rw-r--r--src/main/java/org/anarres/cpp/Warning.java32
33 files changed, 0 insertions, 6419 deletions
diff --git a/src/main/java/org/anarres/cpp/Argument.java b/src/main/java/org/anarres/cpp/Argument.java
deleted file mode 100644
index 31d9e93..0000000
--- a/src/main/java/org/anarres/cpp/Argument.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import javax.annotation.Nonnull;
-
-/**
- * A macro argument.
- *
- * This encapsulates a raw and preprocessed token stream.
- */
-/* pp */ class Argument extends ArrayList<Token> {
-
- private List<Token> expansion;
-
- public Argument() {
- this.expansion = null;
- }
-
- public void addToken(@Nonnull Token tok) {
- add(tok);
- }
-
- /* pp */ void expand(@Nonnull Preprocessor p)
- throws IOException,
- LexerException {
- /* Cache expansion. */
- if (expansion == null) {
- this.expansion = p.expand(this);
- // System.out.println("Expanded arg " + this);
- }
- }
-
- @Nonnull
- public Iterator<Token> expansion() {
- return expansion.iterator();
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("Argument(");
- // buf.append(super.toString());
- buf.append("raw=[ ");
- for (int i = 0; i < size(); i++)
- buf.append(get(i).getText());
- buf.append(" ];expansion=[ ");
- if (expansion == null)
- buf.append("null");
- else
- for (Token token : expansion)
- buf.append(token.getText());
- buf.append(" ])");
- return buf.toString();
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/BuildMetadata.java b/src/main/java/org/anarres/cpp/BuildMetadata.java
deleted file mode 100644
index 79de407..0000000
--- a/src/main/java/org/anarres/cpp/BuildMetadata.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package org.anarres.cpp;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import javax.annotation.Nonnull;
-
-/**
- * Returns information about the build.
- *
- * @author shevek
- */
-public class BuildMetadata {
-
- public static final String RESOURCE = "/META-INF/jcpp.properties";
- private static BuildMetadata INSTANCE;
-
- /** @throws RuntimeException if the properties file cannot be found on the classpath. */
- @Nonnull
- public static synchronized BuildMetadata getInstance() {
- try {
- if (INSTANCE == null)
- INSTANCE = new BuildMetadata();
- return INSTANCE;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
-
- private final Properties properties = new Properties();
-
- private BuildMetadata() throws IOException {
- URL url = BuildMetadata.class.getResource(RESOURCE);
- InputStream in = url.openStream();
- try {
- properties.load(in);
- } finally {
- in.close();
- }
- }
-
- @Nonnull
- public Map<? extends String, ? extends String> asMap() {
- Map<String, String> out = new HashMap<String, String>();
- for (Map.Entry<Object, Object> e : properties.entrySet())
- out.put(String.valueOf(e.getKey()), String.valueOf(e.getValue()));
- return out;
- }
-
- @Nonnull
- public com.github.zafarkhaja.semver.Version getVersion() {
- return com.github.zafarkhaja.semver.Version.valueOf(properties.getProperty("Implementation-Version"));
- }
-
- @Nonnull
- public Date getBuildDate() throws ParseException {
- // Build-Date=2015-01-01_10:09:09
- String text = properties.getProperty("Build-Date");
- SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss");
- return format.parse(text);
- }
-
- public String getChangeId() {
- return properties.getProperty("Change");
- }
-}
diff --git a/src/main/java/org/anarres/cpp/ChrootFileSystem.java b/src/main/java/org/anarres/cpp/ChrootFileSystem.java
deleted file mode 100644
index 1cec184..0000000
--- a/src/main/java/org/anarres/cpp/ChrootFileSystem.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.File;
-import java.io.IOException;
-
-/**
- * A virtual filesystem implementation using java.io in a virtual
- * chroot.
- */
-public class ChrootFileSystem implements VirtualFileSystem {
-
- private File root;
-
- public ChrootFileSystem(File root) {
- this.root = root;
- }
-
- @Override
- public VirtualFile getFile(String path) {
- return new ChrootFile(path);
- }
-
- @Override
- public VirtualFile getFile(String dir, String name) {
- return new ChrootFile(dir, name);
- }
-
- private class ChrootFile extends File implements VirtualFile {
-
- private File rfile;
-
- public ChrootFile(String path) {
- super(path);
- }
-
- public ChrootFile(String dir, String name) {
- super(dir, name);
- }
-
- /* private */
- public ChrootFile(File dir, String name) {
- super(dir, name);
- }
-
- @Override
- public ChrootFile getParentFile() {
- return new ChrootFile(getParent());
- }
-
- @Override
- public ChrootFile getChildFile(String name) {
- return new ChrootFile(this, name);
- }
-
- @Override
- public boolean isFile() {
- File real = new File(root, getPath());
- return real.isFile();
- }
-
- @Override
- public Source getSource() throws IOException {
- return new FileLexerSource(new File(root, getPath()),
- getPath());
- }
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/CppReader.java b/src/main/java/org/anarres/cpp/CppReader.java
deleted file mode 100644
index 5517f47..0000000
--- a/src/main/java/org/anarres/cpp/CppReader.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * 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 javax.annotation.Nonnull;
-import static org.anarres.cpp.Token.CCOMMENT;
-import static org.anarres.cpp.Token.CPPCOMMENT;
-import static org.anarres.cpp.Token.EOF;
-
-/**
- * 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 final Preprocessor cpp;
- private String token;
- private int idx;
-
- public CppReader(@Nonnull final Reader r) {
- cpp = new Preprocessor(new LexerSource(r, true) {
- @Override
- public String getName() {
- return "<CppReader Input@"
- + System.identityHashCode(r) + ">";
- }
- });
- token = "";
- idx = 0;
- }
-
- public CppReader(@Nonnull Preprocessor p) {
- cpp = p;
- token = "";
- idx = 0;
- }
-
- /**
- * Returns the Preprocessor used by this CppReader.
- */
- @Nonnull
- public Preprocessor getPreprocessor() {
- return cpp;
- }
-
- /**
- * Defines the given name as a macro.
- *
- * This is a convnience method.
- */
- public void addMacro(@Nonnull String name)
- throws LexerException {
- cpp.addMacro(name);
- }
-
- /**
- * Defines the given name as a macro.
- *
- * This is a convnience method.
- */
- public void addMacro(@Nonnull String name, @Nonnull 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) {
- throw new IOException(String.valueOf(e), e);
- }
- }
-
- @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 {
- cpp.close();
- token = null;
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/CppTask.java b/src/main/java/org/anarres/cpp/CppTask.java
deleted file mode 100644
index 66df1a6..0000000
--- a/src/main/java/org/anarres/cpp/CppTask.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Enumeration;
-import java.util.List;
-import org.apache.tools.ant.BuildException;
-import org.apache.tools.ant.taskdefs.Copy;
-import org.apache.tools.ant.types.FilterSet;
-import org.apache.tools.ant.types.FilterSetCollection;
-import org.apache.tools.ant.types.Path;
-
-/**
- * An ant task for jcpp.
- */
-public class CppTask extends Copy {
-
- private class Listener extends DefaultPreprocessorListener {
-
- @Override
- protected void print(String msg) {
- log(msg);
- }
- }
-
- public static class Macro {
-
- private String name;
- private String value;
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getName() {
- return name;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public String getValue() {
- return value;
- }
- }
-
- private final Listener listener = new Listener();
- private final List<Macro> macros = new ArrayList<Macro>();
- private Path systemincludepath;
- private Path localincludepath;
-
- public void addMacro(Macro macro) {
- macros.add(macro);
- }
-
- public void addSystemincludepath(Path path) {
- if (systemincludepath == null)
- systemincludepath = new Path(getProject());
- systemincludepath.add(path);
- }
-
- public void addLocalincludepath(Path path) {
- if (localincludepath == null)
- localincludepath = new Path(getProject());
- localincludepath.add(path);
- }
-
- /*
- public void execute() {
- FileWriter writer = null;
- try {
- if (input == null)
- throw new BuildException("Input not specified");
- if (output == null)
- throw new BuildException("Output not specified");
- cpp.addInput(this.input);
- writer = new FileWriter(this.output);
- for (;;) {
- Token tok = cpp.token();
- if (tok != null && tok.getType() == Token.EOF)
- break;
- writer.write(tok.getText());
- }
- }
- catch (Exception e) {
- throw new BuildException(e);
- }
- finally {
- if (writer != null) {
- try {
- writer.close();
- }
- catch (IOException e) {
- }
- }
- }
- }
- */
- private void preprocess(File input, File output) throws Exception {
- Preprocessor cpp = new Preprocessor();
- cpp.setListener(listener);
- for (Macro macro : macros)
- cpp.addMacro(macro.getName(), macro.getValue());
- if (systemincludepath != null)
- cpp.setSystemIncludePath(Arrays.asList(systemincludepath.list()));
- if (localincludepath != null)
- cpp.setQuoteIncludePath(Arrays.asList(localincludepath.list()));
-
- File dir = output.getParentFile();
- if (!dir.exists()) {
- if (!dir.mkdirs())
- throw new BuildException("Failed to make parent directory " + dir);
- } else if (!dir.isDirectory()) {
- throw new BuildException("Parent directory of output file " + output + " exists, but is not a directory.");
- }
- FileWriter writer = null;
- try {
- if (input == null)
- throw new BuildException("Input not specified");
- if (output == null)
- throw new BuildException("Output not specified");
- cpp.addInput(input);
- writer = new FileWriter(output);
- for (;;) {
- Token tok = cpp.token();
- if (tok == null)
- break;
- if (tok.getType() == Token.EOF)
- break;
- writer.write(tok.getText());
- }
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException e) {
- }
- }
- }
- }
-
- @Override
- protected void doFileOperations() {
- if (fileCopyMap.size() > 0) {
- log("Copying " + fileCopyMap.size()
- + " file" + (fileCopyMap.size() == 1 ? "" : "s")
- + " to " + destDir.getAbsolutePath());
-
- Enumeration<String> e = fileCopyMap.keys();
-
- while (e.hasMoreElements()) {
- String fromFile = e.nextElement();
- String[] toFiles = (String[]) fileCopyMap.get(fromFile);
-
- for (String toFile : toFiles) {
- if (fromFile.equals(toFile)) {
- log("Skipping self-copy of " + fromFile, verbosity);
- continue;
- }
-
- try {
- log("Copying " + fromFile + " to " + toFile, verbosity);
-
- FilterSetCollection executionFilters
- = new FilterSetCollection();
- if (filtering) {
- executionFilters
- .addFilterSet(getProject().getGlobalFilterSet());
- }
- for (Enumeration filterEnum = getFilterSets().elements();
- filterEnum.hasMoreElements();) {
- executionFilters
- .addFilterSet((FilterSet) filterEnum.nextElement());
- }
-
- File srcFile = new File(fromFile);
- File dstFile = new File(toFile);
- preprocess(srcFile, dstFile);
- } catch (Exception ioe) {
- // ioe.printStackTrace();
- String msg = "Failed to copy " + fromFile + " to " + toFile
- + " due to " + ioe.getMessage();
- File targetFile = new File(toFile);
- if (targetFile.exists() && !targetFile.delete()) {
- msg += " and I couldn't delete the corrupt " + toFile;
- }
- throw new BuildException(msg, ioe, getLocation());
- }
- }
- }
- }
-
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java b/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java
deleted file mode 100644
index 4d6ee7e..0000000
--- a/src/main/java/org/anarres/cpp/DefaultPreprocessorListener.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package org.anarres.cpp;
-
-/*
- * 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.
- */
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-
-import com.jogamp.gluegen.Logging;
-import com.jogamp.gluegen.Logging.LoggerIf;
-
-/**
- * A handler for preprocessor events, primarily errors and warnings.
- *
- * If no PreprocessorListener is installed in a Preprocessor, all
- * error and warning events will throw an exception. Installing a
- * listener allows more intelligent handling of these events.
- */
-public class DefaultPreprocessorListener implements PreprocessorListener {
-
- private static final LoggerIf LOG = Logging.getLogger(DefaultPreprocessorListener.class);
-
- private int errors;
- private int warnings;
-
- public DefaultPreprocessorListener() {
- clear();
- }
-
- public void clear() {
- errors = 0;
- warnings = 0;
- }
-
- @Nonnegative
- public int getErrors() {
- return errors;
- }
-
- @Nonnegative
- public int getWarnings() {
- return warnings;
- }
-
- protected void print(@Nonnull final String msg) {
- LOG.info(msg);
- }
-
- /**
- * Handles a warning.
- *
- * The behaviour of this method is defined by the
- * implementation. It may simply record the error message, or
- * it may throw an exception.
- */
- @Override
- public void handleWarning(final Source source, final int line, final int column,
- final String msg)
- throws LexerException {
- warnings++;
- print(source.getName() + ":" + line + ":" + column
- + ": warning: " + msg);
- }
-
- /**
- * Handles an error.
- *
- * The behaviour of this method is defined by the
- * implementation. It may simply record the error message, or
- * it may throw an exception.
- */
- @Override
- public void handleError(final Source source, final int line, final int column,
- final String msg)
- throws LexerException {
- errors++;
- print(source.getName() + ":" + line + ":" + column
- + ": error: " + msg);
- }
-
- @Override
- public void handleSourceChange(final Source source, final SourceChangeEvent event) {
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/Feature.java b/src/main/java/org/anarres/cpp/Feature.java
deleted file mode 100644
index 369d79c..0000000
--- a/src/main/java/org/anarres/cpp/Feature.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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;
-
-/**
- * Features of the Preprocessor, which may be enabled or disabled.
- */
-public enum Feature {
-
- /** Supports ANSI digraphs. */
- DIGRAPHS,
- /** Supports ANSI trigraphs. */
- TRIGRAPHS,
- /** Outputs linemarker tokens. */
- LINEMARKERS,
- /** Reports tokens of type INVALID as errors. */
- CSYNTAX,
- /** Preserves comments in the lexed output. */
- KEEPCOMMENTS,
- /** Preserves comments in the lexed output, even when inactive. */
- KEEPALLCOMMENTS,
- DEBUG,
- /** Supports lexing of objective-C. */
- OBJCSYNTAX,
- INCLUDENEXT,
- /** Random extensions. */
- PRAGMA_ONCE
-}
diff --git a/src/main/java/org/anarres/cpp/FileLexerSource.java b/src/main/java/org/anarres/cpp/FileLexerSource.java
deleted file mode 100644
index bdc411f..0000000
--- a/src/main/java/org/anarres/cpp/FileLexerSource.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * 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.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import javax.annotation.Nonnull;
-
-/**
- * A {@link Source} which lexes a file.
- *
- * The input is buffered.
- *
- * @see Source
- */
-public class FileLexerSource extends LexerSource {
-
- private final String path;
- private final File file;
-
- /**
- * Creates a new Source for lexing the given File.
- *
- * Preprocessor directives are honoured within the file.
- */
- public FileLexerSource(@Nonnull File file, String path)
- throws IOException {
- super(
- new BufferedReader(
- new FileReader(
- file
- )
- ),
- true
- );
-
- this.file = file;
- this.path = path;
- }
-
- public FileLexerSource(@Nonnull File file)
- throws IOException {
- this(file, file.getPath());
- }
-
- public FileLexerSource(@Nonnull String path)
- throws IOException {
- this(new File(path), path);
- }
-
- @Nonnull
- public File getFile() {
- return file;
- }
-
- /**
- * This is not necessarily the same as getFile().getPath() in case we are in a chroot.
- */
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public String getName() {
- return getPath();
- }
-
- @Override
- public String toString() {
- return "file " + getPath();
- }
-}
diff --git a/src/main/java/org/anarres/cpp/FixedTokenSource.java b/src/main/java/org/anarres/cpp/FixedTokenSource.java
deleted file mode 100644
index 4d9f41f..0000000
--- a/src/main/java/org/anarres/cpp/FixedTokenSource.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-/* pp */ class FixedTokenSource extends Source {
-
- private static final Token EOF
- = new Token(Token.EOF, "<ts-eof>");
-
- private final List<Token> tokens;
- private int idx;
-
- /* pp */ FixedTokenSource(Token... tokens) {
- this.tokens = Arrays.asList(tokens);
- this.idx = 0;
- }
-
- /* pp */ FixedTokenSource(List<Token> tokens) {
- this.tokens = tokens;
- this.idx = 0;
- }
-
- @Override
- public Token token()
- throws IOException,
- LexerException {
- if (idx >= tokens.size())
- return EOF;
- return tokens.get(idx++);
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("constant token stream ").append(tokens);
- Source parent = getParent();
- if (parent != null)
- buf.append(" in ").append(String.valueOf(parent));
- return buf.toString();
- }
-}
diff --git a/src/main/java/org/anarres/cpp/InputLexerSource.java b/src/main/java/org/anarres/cpp/InputLexerSource.java
deleted file mode 100644
index 93cda54..0000000
--- a/src/main/java/org/anarres/cpp/InputLexerSource.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-
-/**
- * A {@link Source} which lexes a file.
- *
- * The input is buffered.
- *
- * @see Source
- */
-public class InputLexerSource extends LexerSource {
-
- /**
- * Creates a new Source for lexing the given Reader.
- *
- * Preprocessor directives are honoured within the file.
- */
- public InputLexerSource(InputStream input)
- throws IOException {
- super(
- new BufferedReader(
- new InputStreamReader(
- input
- )
- ),
- true
- );
- }
-
- @Override
- public String getPath() {
- return "<standard-input>";
- }
-
- @Override
- public String getName() {
- return "standard input";
- }
-
- @Override
- public String toString() {
- return String.valueOf(getPath());
- }
-}
diff --git a/src/main/java/org/anarres/cpp/InternalException.java b/src/main/java/org/anarres/cpp/InternalException.java
deleted file mode 100644
index fc3b650..0000000
--- a/src/main/java/org/anarres/cpp/InternalException.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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;
-
-/**
- * An internal exception.
- *
- * This exception is thrown when an internal state violation is
- * encountered. This should never happen. If it ever happens, please
- * report it as a bug.
- */
-public class InternalException extends RuntimeException {
-
- public InternalException(String msg) {
- super(msg);
- }
-}
diff --git a/src/main/java/org/anarres/cpp/JavaFileSystem.java b/src/main/java/org/anarres/cpp/JavaFileSystem.java
deleted file mode 100644
index a60271d..0000000
--- a/src/main/java/org/anarres/cpp/JavaFileSystem.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * 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.File;
-import java.io.IOException;
-
-/**
- * A virtual filesystem implementation using java.io.
- */
-public class JavaFileSystem implements VirtualFileSystem {
-
- @Override
- public VirtualFile getFile(String path) {
- return new JavaFile(path);
- }
-
- @Override
- public VirtualFile getFile(String dir, String name) {
- return new JavaFile(dir, name);
- }
-
- private class JavaFile extends File implements VirtualFile {
-
- public JavaFile(String path) {
- super(path);
- }
-
- public JavaFile(String dir, String name) {
- super(dir, name);
- }
-
- /* private */
- public JavaFile(File dir, String name) {
- super(dir, name);
- }
-
- /*
- @Override
- public String getPath() {
- return getCanonicalPath();
- }
- */
- @Override
- public JavaFile getParentFile() {
- String parent = getParent();
- if (parent != null)
- return new JavaFile(parent);
- File absolute = getAbsoluteFile();
- parent = absolute.getParent();
- /*
- if (parent == null)
- return null;
- */
- return new JavaFile(parent);
- }
-
- @Override
- public JavaFile getChildFile(String name) {
- return new JavaFile(this, name);
- }
-
- @Override
- public Source getSource() throws IOException {
- return new FileLexerSource(this);
- }
-
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/JoinReader.java b/src/main/java/org/anarres/cpp/JoinReader.java
deleted file mode 100644
index c39ee79..0000000
--- a/src/main/java/org/anarres/cpp/JoinReader.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * 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;
-
-/* pp */ class JoinReader /* extends Reader */ implements Closeable {
-
- private final Reader in;
-
- private PreprocessorListener listener;
- private LexerSource source;
- private boolean trigraphs;
- private boolean warnings;
-
- private int newlines;
- private boolean flushnl;
- private int[] unget;
- private int uptr;
-
- public JoinReader(Reader in, boolean trigraphs) {
- this.in = in;
- this.trigraphs = trigraphs;
- this.newlines = 0;
- this.flushnl = false;
- this.unget = new int[2];
- this.uptr = 0;
- }
-
- public JoinReader(Reader in) {
- this(in, false);
- }
-
- public void setTrigraphs(boolean enable, boolean warnings) {
- this.trigraphs = enable;
- this.warnings = warnings;
- }
-
- /* pp */ void init(Preprocessor pp, LexerSource s) {
- this.listener = pp.getListener();
- this.source = s;
- setTrigraphs(pp.getFeature(Feature.TRIGRAPHS),
- pp.getWarning(Warning.TRIGRAPHS));
- }
-
- private int __read() throws IOException {
- if (uptr > 0)
- return unget[--uptr];
- return in.read();
- }
-
- private void _unread(int c) {
- if (c != -1)
- unget[uptr++] = c;
- assert uptr <= unget.length :
- "JoinReader ungets too many characters";
- }
-
- protected void warning(String msg)
- throws LexerException {
- if (source != null)
- source.warning(msg);
- else
- throw new LexerException(msg);
- }
-
- private char trigraph(char raw, char repl)
- throws IOException, LexerException {
- if (trigraphs) {
- if (warnings)
- warning("trigraph ??" + raw + " converted to " + repl);
- return repl;
- } else {
- if (warnings)
- warning("trigraph ??" + raw + " ignored");
- _unread(raw);
- _unread('?');
- return '?';
- }
- }
-
- private int _read()
- throws IOException, LexerException {
- int c = __read();
- if (c == '?' && (trigraphs || warnings)) {
- int d = __read();
- if (d == '?') {
- int e = __read();
- switch (e) {
- case '(':
- return trigraph('(', '[');
- case ')':
- return trigraph(')', ']');
- case '<':
- return trigraph('<', '{');
- case '>':
- return trigraph('>', '}');
- case '=':
- return trigraph('=', '#');
- case '/':
- return trigraph('/', '\\');
- case '\'':
- return trigraph('\'', '^');
- case '!':
- return trigraph('!', '|');
- case '-':
- return trigraph('-', '~');
- }
- _unread(e);
- }
- _unread(d);
- }
- return c;
- }
-
- public int read()
- throws IOException, LexerException {
- if (flushnl) {
- if (newlines > 0) {
- newlines--;
- return '\n';
- }
- flushnl = false;
- }
-
- for (;;) {
- int c = _read();
- switch (c) {
- case '\\':
- int d = _read();
- switch (d) {
- case '\n':
- newlines++;
- continue;
- case '\r':
- newlines++;
- int e = _read();
- if (e != '\n')
- _unread(e);
- continue;
- default:
- _unread(d);
- return c;
- }
- case '\r':
- case '\n':
- case '\u2028':
- case '\u2029':
- case '\u000B':
- case '\u000C':
- case '\u0085':
- flushnl = true;
- return c;
- case -1:
- if (newlines > 0) {
- newlines--;
- return '\n';
- }
- default:
- return c;
- }
- }
- }
-
- public int read(char cbuf[], int off, int len)
- throws IOException, LexerException {
- 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 {
- in.close();
- }
-
- @Override
- public String toString() {
- return "JoinReader(nl=" + newlines + ")";
- }
-
- /*
- public static void main(String[] args) throws IOException {
- FileReader f = new FileReader(new File(args[0]));
- BufferedReader b = new BufferedReader(f);
- JoinReader r = new JoinReader(b);
- BufferedWriter w = new BufferedWriter(
- new java.io.OutputStreamWriter(System.out)
- );
- int c;
- while ((c = r.read()) != -1) {
- w.write((char)c);
- }
- w.close();
- }
- */
-}
diff --git a/src/main/java/org/anarres/cpp/LexerException.java b/src/main/java/org/anarres/cpp/LexerException.java
deleted file mode 100644
index d4b2e9c..0000000
--- a/src/main/java/org/anarres/cpp/LexerException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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;
-
-/**
- * A preprocessor exception.
- *
- * Note to users: I don't really like the name of this class. S.
- */
-public class LexerException extends Exception {
-
- public LexerException(String msg) {
- super(msg);
- }
-
- public LexerException(Throwable cause) {
- super(cause);
- }
-}
diff --git a/src/main/java/org/anarres/cpp/LexerSource.java b/src/main/java/org/anarres/cpp/LexerSource.java
deleted file mode 100644
index 82d76b6..0000000
--- a/src/main/java/org/anarres/cpp/LexerSource.java
+++ /dev/null
@@ -1,985 +0,0 @@
-/*
- * 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.IOException;
-import java.io.Reader;
-import javax.annotation.Nonnull;
-import static org.anarres.cpp.Token.*;
-
-/** Does not handle digraphs. */
-public class LexerSource extends Source {
-
- private static final boolean DEBUG = false;
-
- private JoinReader reader;
- private final boolean ppvalid;
- private boolean bol;
- private boolean include;
-
- private boolean digraphs;
-
- /* Unread. */
- private int u0, u1;
- private int ucount;
-
- private int line;
- private int column;
- private int lastcolumn;
- private boolean cr;
-
- /* ppvalid is:
- * false in StringLexerSource,
- * true in FileLexerSource */
- public LexerSource(Reader r, boolean ppvalid) {
- this.reader = new JoinReader(r);
- this.ppvalid = ppvalid;
- this.bol = true;
- this.include = false;
-
- this.digraphs = true;
-
- this.ucount = 0;
-
- this.line = 1;
- this.column = 0;
- this.lastcolumn = -1;
- this.cr = false;
- }
-
- @Override
- /* pp */ void init(Preprocessor pp) {
- super.init(pp);
- this.digraphs = pp.getFeature(Feature.DIGRAPHS);
- this.reader.init(pp, this);
- }
-
- @Override
- public int getLine() {
- return line;
- }
-
- @Override
- public int getColumn() {
- return column;
- }
-
- @Override
- /* pp */ boolean isNumbered() {
- return true;
- }
-
- /* Error handling. */
- private void _error(String msg, boolean error)
- throws LexerException {
- int _l = line;
- int _c = column;
- if (_c == 0) {
- _c = lastcolumn;
- _l--;
- } else {
- _c--;
- }
- if (error)
- super.error(_l, _c, msg);
- else
- super.warning(_l, _c, msg);
- }
-
- /* Allow JoinReader to call this. */
- /* pp */ final void error(String msg)
- throws LexerException {
- _error(msg, true);
- }
-
- /* Allow JoinReader to call this. */
- /* pp */ final void warning(String msg)
- throws LexerException {
- _error(msg, false);
- }
-
- /* A flag for string handling. */
-
- /* pp */ void setInclude(boolean b) {
- this.include = b;
- }
-
- /*
- * private boolean _isLineSeparator(int c) {
- * return Character.getType(c) == Character.LINE_SEPARATOR
- * || c == -1;
- * }
- */
-
- /* XXX Move to JoinReader and canonicalise newlines. */
- private static boolean isLineSeparator(int c) {
- switch ((char) c) {
- case '\r':
- case '\n':
- case '\u2028':
- case '\u2029':
- case '\u000B':
- case '\u000C':
- case '\u0085':
- return true;
- default:
- return (c == -1);
- }
- }
-
- private int read()
- throws IOException,
- LexerException {
- int c;
- assert ucount <= 2 : "Illegal ucount: " + ucount;
- switch (ucount) {
- case 2:
- ucount = 1;
- c = u1;
- break;
- case 1:
- ucount = 0;
- c = u0;
- break;
- default:
- if (reader == null)
- c = -1;
- else
- c = reader.read();
- break;
- }
-
- switch (c) {
- case '\r':
- cr = true;
- line++;
- lastcolumn = column;
- column = 0;
- break;
- case '\n':
- if (cr) {
- cr = false;
- break;
- }
- /* fallthrough */
- case '\u2028':
- case '\u2029':
- case '\u000B':
- case '\u000C':
- case '\u0085':
- cr = false;
- line++;
- lastcolumn = column;
- column = 0;
- break;
- case -1:
- cr = false;
- break;
- default:
- cr = false;
- column++;
- break;
- }
-
- /*
- * if (isLineSeparator(c)) {
- * line++;
- * lastcolumn = column;
- * column = 0;
- * }
- * else {
- * column++;
- * }
- */
- return c;
- }
-
- /* You can unget AT MOST one newline. */
- private void unread(int c)
- throws IOException {
- /* XXX Must unread newlines. */
- if (c != -1) {
- if (isLineSeparator(c)) {
- line--;
- column = lastcolumn;
- cr = false;
- } else {
- column--;
- }
- switch (ucount) {
- case 0:
- u0 = c;
- ucount = 1;
- break;
- case 1:
- u1 = c;
- ucount = 2;
- break;
- default:
- throw new IllegalStateException(
- "Cannot unget another character!"
- );
- }
- // reader.unread(c);
- }
- }
-
- /* Consumes the rest of the current line into an invalid. */
- @Nonnull
- private Token invalid(StringBuilder text, String reason)
- throws IOException,
- LexerException {
- int d = read();
- while (!isLineSeparator(d)) {
- text.append((char) d);
- d = read();
- }
- unread(d);
- return new Token(INVALID, text.toString(), reason);
- }
-
- @Nonnull
- private Token ccomment()
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder("/*");
- int d;
- do {
- do {
- d = read();
- if (d == -1)
- return new Token(INVALID, text.toString(),
- "Unterminated comment");
- text.append((char) d);
- } while (d != '*');
- do {
- d = read();
- if (d == -1)
- return new Token(INVALID, text.toString(),
- "Unterminated comment");
- text.append((char) d);
- } while (d == '*');
- } while (d != '/');
- return new Token(CCOMMENT, text.toString());
- }
-
- @Nonnull
- private Token cppcomment()
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder("//");
- int d = read();
- while (!isLineSeparator(d)) {
- text.append((char) d);
- d = read();
- }
- unread(d);
- return new Token(CPPCOMMENT, text.toString());
- }
-
- private int escape(StringBuilder text)
- throws IOException,
- LexerException {
- int d = read();
- switch (d) {
- case 'a':
- text.append('a');
- return 0x07;
- case 'b':
- text.append('b');
- return '\b';
- case 'f':
- text.append('f');
- return '\f';
- case 'n':
- text.append('n');
- return '\n';
- case 'r':
- text.append('r');
- return '\r';
- case 't':
- text.append('t');
- return '\t';
- case 'v':
- text.append('v');
- return 0x0b;
- case '\\':
- text.append('\\');
- return '\\';
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- int len = 0;
- int val = 0;
- do {
- val = (val << 3) + Character.digit(d, 8);
- text.append((char) d);
- d = read();
- } while (++len < 3 && Character.digit(d, 8) != -1);
- unread(d);
- return val;
-
- case 'x':
- text.append((char) d);
- len = 0;
- val = 0;
- while (len++ < 2) {
- d = read();
- if (Character.digit(d, 16) == -1) {
- unread(d);
- break;
- }
- val = (val << 4) + Character.digit(d, 16);
- text.append((char) d);
- }
- return val;
-
- /* Exclude two cases from the warning. */
- case '"':
- text.append('"');
- return '"';
- case '\'':
- text.append('\'');
- return '\'';
-
- default:
- warning("Unnecessary escape character " + (char) d);
- text.append((char) d);
- return d;
- }
- }
-
- @Nonnull
- private Token character()
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder("'");
- int d = read();
- if (d == '\\') {
- text.append('\\');
- d = escape(text);
- } else if (isLineSeparator(d)) {
- unread(d);
- return new Token(INVALID, text.toString(),
- "Unterminated character literal");
- } else if (d == '\'') {
- text.append('\'');
- return new Token(INVALID, text.toString(),
- "Empty character literal");
- } else if (!Character.isDefined(d)) {
- text.append('?');
- return invalid(text, "Illegal unicode character literal");
- } else {
- text.append((char) d);
- }
-
- int e = read();
- if (e != '\'') {
- // error("Illegal character constant");
- /* We consume up to the next ' or the rest of the line. */
- for (;;) {
- if (isLineSeparator(e)) {
- unread(e);
- break;
- }
- text.append((char) e);
- if (e == '\'')
- break;
- e = read();
- }
- return new Token(INVALID, text.toString(),
- "Illegal character constant " + text);
- }
- text.append('\'');
- /* XXX It this a bad cast? */
- return new Token(CHARACTER,
- text.toString(), Character.valueOf((char) d));
- }
-
- @Nonnull
- private Token string(char open, char close)
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder();
- text.append(open);
-
- StringBuilder buf = new StringBuilder();
-
- for (;;) {
- int c = read();
- if (c == close) {
- break;
- } else if (c == '\\') {
- text.append('\\');
- if (!include) {
- char d = (char) escape(text);
- buf.append(d);
- }
- } else if (c == -1) {
- unread(c);
- // error("End of file in string literal after " + buf);
- return new Token(INVALID, text.toString(),
- "End of file in string literal after " + buf);
- } else if (isLineSeparator(c)) {
- unread(c);
- // error("Unterminated string literal after " + buf);
- return new Token(INVALID, text.toString(),
- "Unterminated string literal after " + buf);
- } else {
- text.append((char) c);
- buf.append((char) c);
- }
- }
- text.append(close);
- switch (close) {
- case '"':
- return new Token(STRING,
- text.toString(), buf.toString());
- case '>':
- return new Token(HEADER,
- text.toString(), buf.toString());
- case '\'':
- if (buf.length() == 1)
- return new Token(CHARACTER,
- text.toString(), buf.toString());
- return new Token(SQSTRING,
- text.toString(), buf.toString());
- default:
- throw new IllegalStateException(
- "Unknown closing character " + String.valueOf(close));
- }
- }
-
- @Nonnull
- private Token _number_suffix(StringBuilder text, NumericValue value, int d)
- throws IOException,
- LexerException {
- int flags = 0; // U, I, L, LL, F, D, MSB
- for (;;) {
- if (d == 'U' || d == 'u') {
- if ((flags & NumericValue.F_UNSIGNED) != 0)
- warning("Duplicate unsigned suffix " + d);
- flags |= NumericValue.F_UNSIGNED;
- text.append((char) d);
- d = read();
- } else if (d == 'L' || d == 'l') {
- if ((flags & NumericValue.FF_SIZE) != 0)
- warning("Multiple length suffixes after " + text);
- text.append((char) d);
- int e = read();
- if (e == d) { // Case must match. Ll is Welsh.
- flags |= NumericValue.F_LONGLONG;
- text.append((char) e);
- d = read();
- } else {
- flags |= NumericValue.F_LONG;
- d = e;
- }
- } else if (d == 'I' || d == 'i') {
- if ((flags & NumericValue.FF_SIZE) != 0)
- warning("Multiple length suffixes after " + text);
- flags |= NumericValue.F_INT;
- text.append((char) d);
- d = read();
- } else if (d == 'F' || d == 'f') {
- if ((flags & NumericValue.FF_SIZE) != 0)
- warning("Multiple length suffixes after " + text);
- flags |= NumericValue.F_FLOAT;
- text.append((char) d);
- d = read();
- } else if (d == 'D' || d == 'd') {
- if ((flags & NumericValue.FF_SIZE) != 0)
- warning("Multiple length suffixes after " + text);
- flags |= NumericValue.F_DOUBLE;
- text.append((char) d);
- d = read();
- }
- else if (Character.isUnicodeIdentifierPart(d)) {
- String reason = "Invalid suffix \"" + (char) d + "\" on numeric constant";
- // We've encountered something initially identified as a number.
- // Read in the rest of this token as an identifer but return it as an invalid.
- while (Character.isUnicodeIdentifierPart(d)) {
- text.append((char) d);
- d = read();
- }
- unread(d);
- return new Token(INVALID, text.toString(), reason);
- } else {
- unread(d);
- value.setFlags(flags);
- return new Token(NUMBER,
- text.toString(), value);
- }
- }
- }
-
- /* Either a decimal part, or a hex exponent. */
- @Nonnull
- private String _number_part(StringBuilder text, int base, boolean sign)
- throws IOException,
- LexerException {
- StringBuilder part = new StringBuilder();
- int d = read();
- if (sign && d == '-') {
- text.append((char) d);
- part.append((char) d);
- d = read();
- }
- while (Character.digit(d, base) != -1) {
- text.append((char) d);
- part.append((char) d);
- d = read();
- }
- unread(d);
- return part.toString();
- }
-
- /* We do not know whether know the first digit is valid. */
- @Nonnull
- private Token number_hex(char x)
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder("0");
- text.append(x);
- String integer = _number_part(text, 16, false);
- NumericValue value = new NumericValue(16, integer);
- int d = read();
- if (d == '.') {
- text.append((char) d);
- String fraction = _number_part(text, 16, false);
- value.setFractionalPart(fraction);
- d = read();
- }
- if (d == 'P' || d == 'p') {
- text.append((char) d);
- String exponent = _number_part(text, 10, true);
- value.setExponent(2, exponent);
- d = read();
- }
- // XXX Make sure it's got enough parts
- return _number_suffix(text, value, d);
- }
-
- private static boolean is_octal(@Nonnull String text) {
- if (!text.startsWith("0"))
- return false;
- for (int i = 0; i < text.length(); i++)
- if (Character.digit(text.charAt(i), 8) == -1)
- return false;
- return true;
- }
-
- /* We know we have at least one valid digit, but empty is not
- * fine. */
- @Nonnull
- private Token number_decimal()
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder();
- String integer = _number_part(text, 10, false);
- String fraction = null;
- String exponent = null;
- int d = read();
- if (d == '.') {
- text.append((char) d);
- fraction = _number_part(text, 10, false);
- d = read();
- }
- if (d == 'E' || d == 'e') {
- text.append((char) d);
- exponent = _number_part(text, 10, true);
- d = read();
- }
- int base = 10;
- if (fraction == null && exponent == null && integer.startsWith("0")) {
- if (!is_octal(integer))
- warning("Decimal constant starts with 0, but not octal: " + integer);
- else
- base = 8;
- }
- NumericValue value = new NumericValue(base, integer);
- if (fraction != null)
- value.setFractionalPart(fraction);
- if (exponent != null)
- value.setExponent(10, exponent);
- // XXX Make sure it's got enough parts
- return _number_suffix(text, value, d);
- }
-
- /**
- * Section 6.4.4.1 of C99
- *
- * (Not pasted here, but says that the initial negation is a separate token.)
- *
- * Section 6.4.4.2 of C99
- *
- * A floating constant has a significand part that may be followed
- * by an exponent part and a suffix that specifies its type. The
- * components of the significand part may include a digit sequence
- * representing the whole-number part, followed by a period (.),
- * followed by a digit sequence representing the fraction part.
- *
- * The components of the exponent part are an e, E, p, or P
- * followed by an exponent consisting of an optionally signed digit
- * sequence. Either the whole-number part or the fraction part has to
- * be present; for decimal floating constants, either the period or
- * the exponent part has to be present.
- *
- * The significand part is interpreted as a (decimal or hexadecimal)
- * rational number; the digit sequence in the exponent part is
- * interpreted as a decimal integer. For decimal floating constants,
- * the exponent indicates the power of 10 by which the significand
- * part is to be scaled. For hexadecimal floating constants, the
- * exponent indicates the power of 2 by which the significand part is
- * to be scaled.
- *
- * For decimal floating constants, and also for hexadecimal
- * floating constants when FLT_RADIX is not a power of 2, the result
- * is either the nearest representable value, or the larger or smaller
- * representable value immediately adjacent to the nearest representable
- * value, chosen in an implementation-defined manner. For hexadecimal
- * floating constants when FLT_RADIX is a power of 2, the result is
- * correctly rounded.
- */
- @Nonnull
- private Token number()
- throws IOException,
- LexerException {
- Token tok;
- int c = read();
- if (c == '0') {
- int d = read();
- if (d == 'x' || d == 'X') {
- tok = number_hex((char) d);
- } else {
- unread(d);
- unread(c);
- tok = number_decimal();
- }
- } else if (Character.isDigit(c) || c == '.') {
- unread(c);
- tok = number_decimal();
- } else {
- throw new LexerException("Asked to parse something as a number which isn't: " + (char) c);
- }
- return tok;
- }
-
- @Nonnull
- private Token identifier(int c)
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder();
- int d;
- text.append((char) c);
- for (;;) {
- d = read();
- if (Character.isIdentifierIgnorable(d))
- ; else if (Character.isJavaIdentifierPart(d))
- text.append((char) d);
- else
- break;
- }
- unread(d);
- return new Token(IDENTIFIER, text.toString());
- }
-
- @Nonnull
- private Token whitespace(int c)
- throws IOException,
- LexerException {
- StringBuilder text = new StringBuilder();
- int d;
- text.append((char) c);
- for (;;) {
- d = read();
- if (ppvalid && isLineSeparator(d)) /* XXX Ugly. */
-
- break;
- if (Character.isWhitespace(d))
- text.append((char) d);
- else
- break;
- }
- unread(d);
- return new Token(WHITESPACE, text.toString());
- }
-
- /* No token processed by cond() contains a newline. */
- @Nonnull
- private Token cond(char c, int yes, int no)
- throws IOException,
- LexerException {
- int d = read();
- if (c == d)
- return new Token(yes);
- unread(d);
- return new Token(no);
- }
-
- @Override
- public Token token()
- throws IOException,
- LexerException {
- Token tok = null;
-
- int _l = line;
- int _c = column;
-
- int c = read();
- int d;
-
- switch (c) {
- case '\n':
- if (ppvalid) {
- bol = true;
- if (include) {
- tok = new Token(NL, _l, _c, "\n");
- } else {
- int nls = 0;
- do {
- nls++;
- d = read();
- } while (d == '\n');
- unread(d);
- char[] text = new char[nls];
- for (int i = 0; i < text.length; i++)
- text[i] = '\n';
- // Skip the bol = false below.
- tok = new Token(NL, _l, _c, new String(text));
- }
- if (DEBUG)
- System.out.println("lx: Returning NL: " + tok);
- return tok;
- }
- /* Let it be handled as whitespace. */
- break;
-
- case '!':
- tok = cond('=', NE, '!');
- break;
-
- case '#':
- if (bol)
- tok = new Token(HASH);
- else
- tok = cond('#', PASTE, '#');
- break;
-
- case '+':
- d = read();
- if (d == '+')
- tok = new Token(INC);
- else if (d == '=')
- tok = new Token(PLUS_EQ);
- else
- unread(d);
- break;
- case '-':
- d = read();
- if (d == '-')
- tok = new Token(DEC);
- else if (d == '=')
- tok = new Token(SUB_EQ);
- else if (d == '>')
- tok = new Token(ARROW);
- else
- unread(d);
- break;
-
- case '*':
- tok = cond('=', MULT_EQ, '*');
- break;
- case '/':
- d = read();
- if (d == '*')
- tok = ccomment();
- else if (d == '/')
- tok = cppcomment();
- else if (d == '=')
- tok = new Token(DIV_EQ);
- else
- unread(d);
- break;
-
- case '%':
- d = read();
- if (d == '=')
- tok = new Token(MOD_EQ);
- else if (digraphs && d == '>')
- tok = new Token('}'); // digraph
- else if (digraphs && d == ':')
- PASTE:
- {
- d = read();
- if (d != '%') {
- unread(d);
- tok = new Token('#'); // digraph
- break PASTE;
- }
- d = read();
- if (d != ':') {
- unread(d); // Unread 2 chars here.
- unread('%');
- tok = new Token('#'); // digraph
- break PASTE;
- }
- tok = new Token(PASTE); // digraph
- }
- else
- unread(d);
- break;
-
- case ':':
- /* :: */
- d = read();
- if (digraphs && d == '>')
- tok = new Token(']'); // digraph
- else
- unread(d);
- break;
-
- case '<':
- if (include) {
- tok = string('<', '>');
- } else {
- d = read();
- if (d == '=')
- tok = new Token(LE);
- else if (d == '<')
- tok = cond('=', LSH_EQ, LSH);
- else if (digraphs && d == ':')
- tok = new Token('['); // digraph
- else if (digraphs && d == '%')
- tok = new Token('{'); // digraph
- else
- unread(d);
- }
- break;
-
- case '=':
- tok = cond('=', EQ, '=');
- break;
-
- case '>':
- d = read();
- if (d == '=')
- tok = new Token(GE);
- else if (d == '>')
- tok = cond('=', RSH_EQ, RSH);
- else
- unread(d);
- break;
-
- case '^':
- tok = cond('=', XOR_EQ, '^');
- break;
-
- case '|':
- d = read();
- if (d == '=')
- tok = new Token(OR_EQ);
- else if (d == '|')
- tok = cond('=', LOR_EQ, LOR);
- else
- unread(d);
- break;
- case '&':
- d = read();
- if (d == '&')
- tok = cond('=', LAND_EQ, LAND);
- else if (d == '=')
- tok = new Token(AND_EQ);
- else
- unread(d);
- break;
-
- case '.':
- d = read();
- if (d == '.')
- tok = cond('.', ELLIPSIS, RANGE);
- else
- unread(d);
- if (Character.isDigit(d)) {
- unread('.');
- tok = number();
- }
- /* XXX decimal fraction */
- break;
-
- case '\'':
- tok = string('\'', '\'');
- break;
-
- case '"':
- tok = string('"', '"');
- break;
-
- case -1:
- close();
- tok = new Token(EOF, _l, _c, "<eof>");
- break;
- }
-
- if (tok == null) {
- if (Character.isWhitespace(c)) {
- tok = whitespace(c);
- } else if (Character.isDigit(c)) {
- unread(c);
- tok = number();
- } else if (Character.isJavaIdentifierStart(c)) {
- tok = identifier(c);
- } else {
- tok = new Token(c);
- }
- }
-
- if (bol) {
- switch (tok.getType()) {
- case WHITESPACE:
- case CCOMMENT:
- break;
- default:
- bol = false;
- break;
- }
- }
-
- tok.setLocation(_l, _c);
- if (DEBUG)
- System.out.println("lx: Returning " + tok);
- // (new Exception("here")).printStackTrace(System.out);
- return tok;
- }
-
- @Override
- public void close()
- throws IOException {
- if (reader != null) {
- reader.close();
- reader = null;
- }
- super.close();
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/Macro.java b/src/main/java/org/anarres/cpp/Macro.java
deleted file mode 100644
index ce00930..0000000
--- a/src/main/java/org/anarres/cpp/Macro.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * A macro object.
- *
- * This encapsulates a name, an argument count, and a token stream
- * for replacement. The replacement token stream may contain the
- * extra tokens {@link Token#M_ARG} and {@link Token#M_STRING}.
- */
-public class Macro {
-
- private Source source;
- private final String name;
- /* It's an explicit decision to keep these around here. We don't
- * need to; the argument token type is M_ARG and the value
- * is the index. The strings themselves are only used in
- * stringification of the macro, for debugging. */
- private List<String> args;
- private boolean variadic;
- private List<Token> tokens;
-
- public Macro(final Source source, final String name) {
- this.source = source;
- this.name = name;
- this.args = null;
- this.variadic = false;
- this.tokens = new ArrayList<Token>();
- }
-
- public Macro(final String name) {
- this(null, name);
- }
-
- /**
- * Sets the Source from which this macro was parsed.
- */
- public void setSource(final Source s) {
- this.source = s;
- }
-
- /**
- * Returns the Source from which this macro was parsed.
- *
- * This method may return null if the macro was not parsed
- * from a regular file.
- */
- public Source getSource() {
- return source;
- }
-
- /**
- * Returns the name of this macro.
- */
- public String getName() {
- return name;
- }
-
- /**
- * Sets the arguments to this macro.
- */
- public void setArgs(final List<String> args) {
- this.args = args;
- }
-
- /**
- * Returns true if this is a function-like macro.
- */
- public boolean isFunctionLike() {
- return args != null;
- }
-
- /**
- * Returns the number of arguments to this macro.
- */
- public int getArgs() {
- return args.size();
- }
-
- /**
- * Sets the variadic flag on this Macro.
- */
- public void setVariadic(final boolean b) {
- this.variadic = b;
- }
-
- /**
- * Returns true if this is a variadic function-like macro.
- */
- public boolean isVariadic() {
- return variadic;
- }
-
- /**
- * Adds a token to the expansion of this macro.
- */
- public void addToken(final Token tok) {
- this.tokens.add(tok);
- }
-
- /**
- * Adds a "paste" operator to the expansion of this macro.
- *
- * A paste operator causes the next token added to be pasted
- * to the previous token when the macro is expanded.
- * It is an error for a macro to end with a paste token.
- */
- public void addPaste(final Token tok) {
- /*
- * Given: tok0 ## tok1
- * We generate: M_PASTE, tok0, tok1
- * This extends as per a stack language:
- * tok0 ## tok1 ## tok2 ->
- * M_PASTE, tok0, M_PASTE, tok1, tok2
- */
- this.tokens.add(tokens.size() - 1, tok);
- }
-
- /* pp */ List<Token> getTokens() {
- return tokens;
- }
- /* pp */ void setTokens(final List<Token> tokens) {
- this.tokens = tokens;
- }
-
- /* Paste tokens are inserted before the first of the two pasted
- * tokens, so it's a kind of bytecode notation. This method
- * swaps them around again. We know that there will never be two
- * sequential paste tokens, so a boolean is sufficient. */
- public String getText() {
- final StringBuilder buf = new StringBuilder();
- boolean paste = false;
- for (final Token tok : tokens) {
- if (tok.getType() == Token.M_PASTE) {
- assert paste == false : "Two sequential pastes.";
- paste = true;
- continue;
- } else {
- buf.append(tok.getText());
- }
- if (paste) {
- buf.append(" #" + "# ");
- paste = false;
- }
- // buf.append(tokens.get(i));
- }
- return buf.toString();
- }
-
- @Override
- public String toString() {
- final StringBuilder buf = new StringBuilder(name);
- if (args != null) {
- buf.append('(');
- final Iterator<String> it = args.iterator();
- while (it.hasNext()) {
- buf.append(it.next());
- if (it.hasNext())
- buf.append(", ");
- else if (isVariadic())
- buf.append("...");
- }
- buf.append(')');
- }
- if (!tokens.isEmpty()) {
- buf.append(" => ").append(getText());
- }
- return buf.toString();
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/MacroTokenSource.java b/src/main/java/org/anarres/cpp/MacroTokenSource.java
deleted file mode 100644
index b512c3d..0000000
--- a/src/main/java/org/anarres/cpp/MacroTokenSource.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * 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.IOException;
-import java.util.Iterator;
-import java.util.List;
-import javax.annotation.Nonnull;
-import static org.anarres.cpp.Token.*;
-
-/* This source should always be active, since we don't expand macros
- * in any inactive context. */
-/* pp */ class MacroTokenSource extends Source {
-
- private final Macro macro;
- private final Iterator<Token> tokens; /* Pointer into the macro. */
-
- private final List<Argument> args; /* { unexpanded, expanded } */
-
- private Iterator<Token> arg; /* "current expansion" */
-
- /* pp */ MacroTokenSource(@Nonnull Macro m, @Nonnull List<Argument> args) {
- this.macro = m;
- this.tokens = m.getTokens().iterator();
- this.args = args;
- this.arg = null;
- }
-
- @Override
- /* pp */ boolean isExpanding(@Nonnull Macro m) {
- /* When we are expanding an arg, 'this' macro is not
- * being expanded, and thus we may re-expand it. */
- if (/* XXX this.arg == null && */this.macro == m)
- return true;
- return super.isExpanding(m);
- }
-
- /* XXX Called from Preprocessor [ugly]. */
- /* pp */ static void escape(@Nonnull StringBuilder buf, @Nonnull CharSequence cs) {
- if (buf == null)
- throw new NullPointerException("Buffer was null.");
- if (cs == null)
- throw new NullPointerException("CharSequence was null.");
- for (int i = 0; i < cs.length(); i++) {
- char c = cs.charAt(i);
- switch (c) {
- case '\\':
- buf.append("\\\\");
- break;
- case '"':
- buf.append("\\\"");
- break;
- case '\n':
- buf.append("\\n");
- break;
- case '\r':
- buf.append("\\r");
- break;
- default:
- buf.append(c);
- }
- }
- }
-
- private void concat(@Nonnull StringBuilder buf, @Nonnull Argument arg) {
- for (Token tok : arg) {
- buf.append(tok.getText());
- }
- }
-
- @Nonnull
- private Token stringify(@Nonnull Token pos, @Nonnull Argument arg) {
- StringBuilder buf = new StringBuilder();
- concat(buf, arg);
- // System.out.println("Concat: " + arg + " -> " + buf);
- StringBuilder str = new StringBuilder("\"");
- escape(str, buf);
- str.append("\"");
- // System.out.println("Escape: " + buf + " -> " + str);
- return new Token(STRING,
- pos.getLine(), pos.getColumn(),
- str.toString(), buf.toString());
- }
-
-
- /* At this point, we have consumed the first M_PASTE.
- * @see Macro#addPaste(Token) */
- private void paste(@Nonnull Token ptok)
- throws IOException,
- LexerException {
- StringBuilder buf = new StringBuilder();
- // Token err = null;
- /* We know here that arg is null or expired,
- * since we cannot paste an expanded arg. */
-
- int count = 2;
- for (int i = 0; i < count; i++) {
- if (!tokens.hasNext()) {
- /* XXX This one really should throw. */
- error(ptok.getLine(), ptok.getColumn(),
- "Paste at end of expansion");
- buf.append(' ').append(ptok.getText());
- break;
- }
- Token tok = tokens.next();
- // System.out.println("Paste " + tok);
- switch (tok.getType()) {
- case M_PASTE:
- /* One extra to paste, plus one because the
- * paste token didn't count. */
- count += 2;
- ptok = tok;
- break;
- case M_ARG:
- int idx = ((Integer) tok.getValue()).intValue();
- concat(buf, args.get(idx));
- break;
- /* XXX Test this. */
- case CCOMMENT:
- case CPPCOMMENT:
- break;
- default:
- buf.append(tok.getText());
- break;
- }
- }
-
- /* Push and re-lex. */
- /*
- StringBuilder src = new StringBuilder();
- escape(src, buf);
- StringLexerSource sl = new StringLexerSource(src.toString());
- */
- StringLexerSource sl = new StringLexerSource(buf.toString());
-
- /* XXX Check that concatenation produces a valid token. */
- arg = new SourceIterator(sl);
- }
-
- @Override
- public Token token()
- throws IOException,
- LexerException {
- for (;;) {
- /* Deal with lexed tokens first. */
-
- if (arg != null) {
- if (arg.hasNext()) {
- Token tok = arg.next();
- /* XXX PASTE -> INVALID. */
- assert tok.getType() != M_PASTE :
- "Unexpected paste token";
- return tok;
- }
- arg = null;
- }
-
- if (!tokens.hasNext())
- return new Token(EOF, -1, -1, ""); /* End of macro. */
-
- Token tok = tokens.next();
- int idx;
- switch (tok.getType()) {
- case M_STRING:
- /* Use the nonexpanded arg. */
- idx = ((Integer) tok.getValue()).intValue();
- return stringify(tok, args.get(idx));
- case M_ARG:
- /* Expand the arg. */
- idx = ((Integer) tok.getValue()).intValue();
- // System.out.println("Pushing arg " + args.get(idx));
- arg = args.get(idx).expansion();
- break;
- case M_PASTE:
- paste(tok);
- break;
- default:
- return tok;
- }
- } /* for */
-
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append("expansion of ").append(macro.getName());
- Source parent = getParent();
- if (parent != null)
- buf.append(" in ").append(String.valueOf(parent));
- return buf.toString();
- }
-}
diff --git a/src/main/java/org/anarres/cpp/Main.java b/src/main/java/org/anarres/cpp/Main.java
deleted file mode 100644
index acf2436..0000000
--- a/src/main/java/org/anarres/cpp/Main.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * 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.File;
-import java.io.PrintStream;
-import java.util.Arrays;
-import java.util.EnumSet;
-import java.util.List;
-import javax.annotation.Nonnull;
-import joptsimple.OptionParser;
-import joptsimple.OptionSet;
-import joptsimple.OptionSpec;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * (Currently a simple test class).
- */
-public class Main {
-
- private static final Logger LOG = LoggerFactory.getLogger(Main.class);
-
- @Nonnull
- private static CharSequence getWarnings() {
- StringBuilder buf = new StringBuilder();
- for (Warning w : Warning.values()) {
- if (buf.length() > 0)
- buf.append(", ");
- String name = w.name().toLowerCase();
- buf.append(name.replace('_', '-'));
- }
- return buf;
- }
-
- public static void main(String[] args) throws Exception {
- (new Main()).run(args);
- }
-
- public void run(String[] args) throws Exception {
-
- OptionParser parser = new OptionParser();
- OptionSpec<?> helpOption = parser.accepts("help",
- "Displays command-line help.")
- .forHelp();
- OptionSpec<?> versionOption = parser.acceptsAll(Arrays.asList("version"),
- "Displays the product version (" + BuildMetadata.getInstance().getVersion() + ") and exits.")
- .forHelp();
-
- OptionSpec<?> debugOption = parser.acceptsAll(Arrays.asList("debug"),
- "Enables debug output.");
-
- OptionSpec<String> defineOption = parser.acceptsAll(Arrays.asList("define", "D"),
- "Defines the given macro.")
- .withRequiredArg().ofType(String.class).describedAs("name[=definition]");
- OptionSpec<String> undefineOption = parser.acceptsAll(Arrays.asList("undefine", "U"),
- "Undefines the given macro, previously either builtin or defined using -D.")
- .withRequiredArg().describedAs("name");
- OptionSpec<File> includeOption = parser.accepts("include",
- "Process file as if \"#" + "include \"file\"\" appeared as the first line of the primary source file.")
- .withRequiredArg().ofType(File.class).describedAs("file");
- OptionSpec<File> incdirOption = parser.acceptsAll(Arrays.asList("incdir", "I"),
- "Adds the directory dir to the list of directories to be searched for header files.")
- .withRequiredArg().ofType(File.class).describedAs("dir");
- OptionSpec<File> iquoteOption = parser.acceptsAll(Arrays.asList("iquote"),
- "Adds the directory dir to the list of directories to be searched for header files included using \"\".")
- .withRequiredArg().ofType(File.class).describedAs("dir");
- OptionSpec<String> warningOption = parser.acceptsAll(Arrays.asList("warning", "W"),
- "Enables the named warning class (" + getWarnings() + ").")
- .withRequiredArg().ofType(String.class).describedAs("warning");
- OptionSpec<Void> noWarningOption = parser.acceptsAll(Arrays.asList("no-warnings", "w"),
- "Disables ALL warnings.");
- OptionSpec<File> inputsOption = parser.nonOptions()
- .ofType(File.class).describedAs("Files to process.");
-
- OptionSet options = parser.parse(args);
-
- if (options.has(helpOption)) {
- parser.printHelpOn(System.out);
- return;
- }
-
- if (options.has(versionOption)) {
- version(System.out);
- return;
- }
-
- Preprocessor pp = new Preprocessor();
- pp.addFeature(Feature.DIGRAPHS);
- pp.addFeature(Feature.TRIGRAPHS);
- pp.addFeature(Feature.LINEMARKERS);
- pp.addWarning(Warning.IMPORT);
- pp.setListener(new DefaultPreprocessorListener());
- pp.addMacro("__JCPP__");
- pp.getSystemIncludePath().add("/usr/local/include");
- pp.getSystemIncludePath().add("/usr/include");
- pp.getFrameworksPath().add("/System/Library/Frameworks");
- pp.getFrameworksPath().add("/Library/Frameworks");
- pp.getFrameworksPath().add("/Local/Library/Frameworks");
-
- if (options.has(debugOption))
- pp.addFeature(Feature.DEBUG);
-
- if (options.has(noWarningOption))
- pp.getWarnings().clear();
-
- for (String warning : options.valuesOf(warningOption)) {
- warning = warning.toUpperCase();
- warning = warning.replace('-', '_');
- if (warning.equals("ALL"))
- pp.addWarnings(EnumSet.allOf(Warning.class));
- else
- pp.addWarning(Enum.valueOf(Warning.class, warning));
- }
-
- for (String arg : options.valuesOf(defineOption)) {
- int idx = arg.indexOf('=');
- if (idx == -1)
- pp.addMacro(arg);
- else
- pp.addMacro(arg.substring(0, idx), arg.substring(idx + 1));
- }
- for (String arg : options.valuesOf(undefineOption)) {
- pp.getMacros().remove(arg);
- }
-
- for (File dir : options.valuesOf(incdirOption))
- pp.getSystemIncludePath().add(dir.getAbsolutePath());
- for (File dir : options.valuesOf(iquoteOption))
- pp.getQuoteIncludePath().add(dir.getAbsolutePath());
- for (File file : options.valuesOf(includeOption))
- // Comply exactly with spec.
- pp.addInput(new StringLexerSource("#" + "include \"" + file + "\"\n"));
-
- List<File> inputs = options.valuesOf(inputsOption);
- if (inputs.isEmpty()) {
- pp.addInput(new InputLexerSource(System.in));
- } else {
- for (File input : inputs)
- pp.addInput(new FileLexerSource(input));
- }
-
- if (pp.getFeature(Feature.DEBUG)) {
- LOG.info("#" + "include \"...\" search starts here:");
- for (String dir : pp.getQuoteIncludePath())
- LOG.info(" " + dir);
- LOG.info("#" + "include <...> search starts here:");
- for (String dir : pp.getSystemIncludePath())
- LOG.info(" " + dir);
- LOG.info("End of search list.");
- }
-
- try {
- for (;;) {
- Token tok = pp.token();
- if (tok == null)
- break;
- if (tok.getType() == Token.EOF)
- break;
- System.out.print(tok.getText());
- }
- } catch (Exception e) {
- StringBuilder buf = new StringBuilder("Preprocessor failed:\n");
- Source s = pp.getSource();
- while (s != null) {
- buf.append(" -> ").append(s).append("\n");
- s = s.getParent();
- }
- LOG.error(buf.toString(), e);
- }
-
- }
-
- private static void version(@Nonnull PrintStream out) {
- BuildMetadata metadata = BuildMetadata.getInstance();
- out.println("Anarres Java C Preprocessor version " + metadata.getVersion() + " change-id " + metadata.getChangeId());
- out.println("Copyright (C) 2008-2014 Shevek (http://www.anarres.org/).");
- out.println("This is free software; see the source for copying conditions. There is NO");
- out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
- }
-}
diff --git a/src/main/java/org/anarres/cpp/NumericValue.java b/src/main/java/org/anarres/cpp/NumericValue.java
deleted file mode 100644
index e4235d3..0000000
--- a/src/main/java/org/anarres/cpp/NumericValue.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * 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.math.BigDecimal;
-import java.math.BigInteger;
-import javax.annotation.CheckForNull;
-import javax.annotation.CheckForSigned;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-
-public class NumericValue extends Number {
-
- public static final int F_UNSIGNED = 1;
- public static final int F_INT = 2;
- public static final int F_LONG = 4;
- public static final int F_LONGLONG = 8;
- public static final int F_FLOAT = 16;
- public static final int F_DOUBLE = 32;
-
- public static final int FF_SIZE = F_INT | F_LONG | F_LONGLONG | F_FLOAT | F_DOUBLE;
-
- private final int base;
- private final String integer;
- private String fraction;
- private int expbase = 0;
- private String exponent;
- private int flags;
-
- public NumericValue(int base, String integer) {
- this.base = base;
- this.integer = integer;
- }
-
- @Nonnegative
- public int getBase() {
- return base;
- }
-
- @Nonnull
- public String getIntegerPart() {
- return integer;
- }
-
- @CheckForNull
- public String getFractionalPart() {
- return fraction;
- }
-
- /* pp */ void setFractionalPart(String fraction) {
- this.fraction = fraction;
- }
-
- @CheckForSigned
- public int getExponentBase() {
- return expbase;
- }
-
- @CheckForNull
- public String getExponent() {
- return exponent;
- }
-
- /* pp */ void setExponent(int expbase, String exponent) {
- this.expbase = expbase;
- this.exponent = exponent;
- }
-
- public int getFlags() {
- return flags;
- }
-
- /* pp */ void setFlags(int flags) {
- this.flags = flags;
- }
-
- /**
- * So, it turns out that parsing arbitrary bases into arbitrary
- * precision numbers is nontrivial, and this routine gets it wrong
- * in many important cases.
- */
- @Nonnull
- public BigDecimal toBigDecimal() {
- int scale = 0;
- String text = getIntegerPart();
- String t_fraction = getFractionalPart();
- if (t_fraction != null) {
- text += getFractionalPart();
- // XXX Wrong for anything but base 10.
- scale += t_fraction.length();
- }
- String t_exponent = getExponent();
- if (t_exponent != null)
- scale -= Integer.parseInt(t_exponent);
- BigInteger unscaled = new BigInteger(text, getBase());
- return new BigDecimal(unscaled, scale);
- }
-
- @Nonnull
- public Number toJavaLangNumber() {
- int flags = getFlags();
- if ((flags & F_DOUBLE) != 0)
- return doubleValue();
- else if ((flags & F_FLOAT) != 0)
- return floatValue();
- else if ((flags & (F_LONG | F_LONGLONG)) != 0)
- return longValue();
- else if ((flags & F_INT) != 0)
- return intValue();
- else if (getFractionalPart() != null)
- return doubleValue(); // .1 is a double in Java.
- else if (getExponent() != null)
- return doubleValue();
- else
- return intValue();
- }
-
- private int exponentValue() {
- return Integer.parseInt(exponent, 10);
- }
-
- @Override
- public int intValue() {
- int v = integer.isEmpty() ? 0 : Integer.parseInt(integer, base);
- if (expbase == 2)
- v = v << exponentValue();
- else if (expbase != 0)
- v = (int) (v * Math.pow(expbase, exponentValue()));
- return v;
- }
-
- @Override
- public long longValue() {
- long v = integer.isEmpty() ? 0 : Long.parseLong(integer, base);
- if (expbase == 2)
- v = v << exponentValue();
- else if (expbase != 0)
- v = (long) (v * Math.pow(expbase, exponentValue()));
- return v;
- }
-
- @Override
- public float floatValue() {
- if (getBase() != 10)
- return longValue();
- return Float.parseFloat(toString());
- }
-
- @Override
- public double doubleValue() {
- if (getBase() != 10)
- return longValue();
- return Double.parseDouble(toString());
- }
-
- private boolean appendFlags(StringBuilder buf, String suffix, int flag) {
- if ((getFlags() & flag) != flag)
- return false;
- buf.append(suffix);
- return true;
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- switch (base) {
- case 8:
- buf.append('0');
- break;
- case 10:
- break;
- case 16:
- buf.append("0x");
- break;
- case 2:
- buf.append('b');
- break;
- default:
- buf.append("[base-").append(base).append("]");
- break;
- }
- buf.append(getIntegerPart());
- if (getFractionalPart() != null)
- buf.append('.').append(getFractionalPart());
- if (getExponent() != null) {
- buf.append(base > 10 ? 'p' : 'e');
- buf.append(getExponent());
- }
- /*
- if (appendFlags(buf, "ui", F_UNSIGNED | F_INT));
- else if (appendFlags(buf, "ul", F_UNSIGNED | F_LONG));
- else if (appendFlags(buf, "ull", F_UNSIGNED | F_LONGLONG));
- else if (appendFlags(buf, "i", F_INT));
- else if (appendFlags(buf, "l", F_LONG));
- else if (appendFlags(buf, "ll", F_LONGLONG));
- else if (appendFlags(buf, "f", F_FLOAT));
- else if (appendFlags(buf, "d", F_DOUBLE));
- */
- return buf.toString();
- }
-}
diff --git a/src/main/java/org/anarres/cpp/Preprocessor.java b/src/main/java/org/anarres/cpp/Preprocessor.java
deleted file mode 100644
index c7a106a..0000000
--- a/src/main/java/org/anarres/cpp/Preprocessor.java
+++ /dev/null
@@ -1,2154 +0,0 @@
-/*
- * 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.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.TreeMap;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-import static org.anarres.cpp.PreprocessorCommand.*;
-
-import org.anarres.cpp.PreprocessorListener.SourceChangeEvent;
-
-import com.jogamp.gluegen.Logging;
-import com.jogamp.gluegen.Logging.LoggerIf;
-
-import static org.anarres.cpp.Token.*;
-
-/**
- * A C Preprocessor.
- * The Preprocessor outputs a token stream which does not need
- * re-lexing for C or C++. Alternatively, the output text may be
- * reconstructed by concatenating the {@link Token#getText() text}
- * values of the returned {@link Token Tokens}. (See
- * {@link CppReader}, which does this.)
- */
-/*
- * Source file name and line number information is conveyed by lines of the form
- *
- * # linenum filename flags
- *
- * These are called linemarkers. They are inserted as needed into
- * the output (but never within a string or character constant). They
- * mean that the following line originated in file filename at line
- * linenum. filename will never contain any non-printing characters;
- * they are replaced with octal escape sequences.
- *
- * After the file name comes zero or more flags, which are `1', `2',
- * `3', or `4'. If there are multiple flags, spaces separate them. Here
- * is what the flags mean:
- *
- * `1'
- * This indicates the start of a new file.
- * `2'
- * This indicates returning to a file (after having included another
- * file).
- * `3'
- * This indicates that the following text comes from a system header
- * file, so certain warnings should be suppressed.
- * `4'
- * This indicates that the following text should be treated as being
- * wrapped in an implicit extern "C" block.
- */
-public class Preprocessor implements Closeable {
-
- private static final LoggerIf LOG = Logging.getLogger(Preprocessor.class);
-
- private static final Source INTERNAL = new Source() {
- @Override
- public Token token()
- throws IOException,
- LexerException {
- throw new LexerException("Cannot read from " + getName());
- }
-
- @Override
- public String getPath() {
- return "<internal-data>";
- }
-
- @Override
- public String getName() {
- return "internal data";
- }
- };
- private static final Macro __LINE__ = new Macro(INTERNAL, "__LINE__");
- private static final Macro __FILE__ = new Macro(INTERNAL, "__FILE__");
- private static final Macro __COUNTER__ = new Macro(INTERNAL, "__COUNTER__");
-
- private final List<Source> inputs;
-
- /* The fundamental engine. */
- private final Map<String, Macro> macros;
- private final Stack<State> states;
- private Source source;
-
- /* Miscellaneous support. */
- private int counter;
- private final Set<String> onceseenpaths = new HashSet<String>();
- private final List<VirtualFile> includes = new ArrayList<VirtualFile>();
-
- /* Support junk to make it work like cpp */
- private List<String> quoteincludepath; /* -iquote */
-
- private List<String> sysincludepath; /* -I */
-
- private List<String> frameworkspath;
- private final Set<Feature> features;
- private final Set<Warning> warnings;
- private VirtualFileSystem filesystem;
- private PreprocessorListener listener;
-
- public Preprocessor() {
- this.inputs = new ArrayList<Source>();
-
- this.macros = new HashMap<String, Macro>();
- macros.put(__LINE__.getName(), __LINE__);
- macros.put(__FILE__.getName(), __FILE__);
- macros.put(__COUNTER__.getName(), __COUNTER__);
- this.states = new Stack<State>();
- states.push(new State());
- this.source = null;
-
- this.counter = 0;
-
- this.quoteincludepath = new ArrayList<String>();
- this.sysincludepath = new ArrayList<String>();
- this.frameworkspath = new ArrayList<String>();
- this.features = EnumSet.noneOf(Feature.class);
- this.warnings = EnumSet.noneOf(Warning.class);
- this.filesystem = new JavaFileSystem();
- this.listener = null;
- }
-
- public Preprocessor(@Nonnull final Source initial) {
- this();
- addInput(initial);
- }
-
- /** Equivalent to
- * 'new Preprocessor(new {@link FileLexerSource}(file))'
- */
- public Preprocessor(@Nonnull final File file)
- throws IOException {
- this(new FileLexerSource(file));
- }
-
- /**
- * Sets the VirtualFileSystem used by this Preprocessor.
- */
- public void setFileSystem(@Nonnull final VirtualFileSystem filesystem) {
- this.filesystem = filesystem;
- }
-
- /**
- * Returns the VirtualFileSystem used by this Preprocessor.
- */
- @Nonnull
- public VirtualFileSystem getFileSystem() {
- return filesystem;
- }
-
- /**
- * Sets the PreprocessorListener which handles events for
- * this Preprocessor.
- *
- * The listener is notified of warnings, errors and source
- * changes, amongst other things.
- */
- public void setListener(@Nonnull final PreprocessorListener listener) {
- this.listener = listener;
- Source s = source;
- while (s != null) {
- // s.setListener(listener);
- s.init(this);
- s = s.getParent();
- }
- }
-
- /**
- * Returns the PreprocessorListener which handles events for
- * this Preprocessor.
- */
- @Nonnull
- public PreprocessorListener getListener() {
- return listener;
- }
-
- /**
- * Returns the feature-set for this Preprocessor.
- *
- * This set may be freely modified by user code.
- */
- @Nonnull
- public Set<Feature> getFeatures() {
- return features;
- }
-
- /**
- * Adds a feature to the feature-set of this Preprocessor.
- */
- public void addFeature(@Nonnull final Feature f) {
- features.add(f);
- }
-
- /**
- * Adds features to the feature-set of this Preprocessor.
- */
- public void addFeatures(@Nonnull final Collection<Feature> f) {
- features.addAll(f);
- }
-
- /**
- * Adds features to the feature-set of this Preprocessor.
- */
- public void addFeatures(final Feature... f) {
- addFeatures(Arrays.asList(f));
- }
-
- /**
- * Returns true if the given feature is in
- * the feature-set of this Preprocessor.
- */
- public boolean getFeature(@Nonnull final Feature f) {
- return features.contains(f);
- }
-
- /**
- * Returns the warning-set for this Preprocessor.
- *
- * This set may be freely modified by user code.
- */
- @Nonnull
- public Set<Warning> getWarnings() {
- return warnings;
- }
-
- /**
- * Adds a warning to the warning-set of this Preprocessor.
- */
- public void addWarning(@Nonnull final Warning w) {
- warnings.add(w);
- }
-
- /**
- * Adds warnings to the warning-set of this Preprocessor.
- */
- public void addWarnings(@Nonnull final Collection<Warning> w) {
- warnings.addAll(w);
- }
-
- /**
- * Returns true if the given warning is in
- * the warning-set of this Preprocessor.
- */
- public boolean getWarning(@Nonnull final Warning w) {
- return warnings.contains(w);
- }
-
- /**
- * Adds input for the Preprocessor.
- *
- * Inputs are processed in the order in which they are added.
- */
- public void addInput(@Nonnull final Source source) {
- source.init(this);
- inputs.add(source);
- }
-
- /**
- * Adds input for the Preprocessor.
- *
- * @see #addInput(Source)
- */
- public void addInput(@Nonnull final File file)
- throws IOException {
- addInput(new FileLexerSource(file));
- }
-
- /**
- * Handles an error.
- *
- * If a PreprocessorListener is installed, it receives the
- * error. Otherwise, an exception is thrown.
- */
- protected void error(final int line, final int column, @Nonnull final String msg)
- throws LexerException {
- if (listener != null)
- listener.handleError(source, line, column, msg);
- else
- throw new LexerException("Error at " + line + ":" + column + ": " + msg);
- }
-
- /**
- * Handles an error.
- *
- * If a PreprocessorListener is installed, it receives the
- * error. Otherwise, an exception is thrown.
- *
- * @see #error(int, int, String)
- */
- protected void error(@Nonnull final Token tok, @Nonnull final String msg)
- throws LexerException {
- error(tok.getLine(), tok.getColumn(), msg);
- }
-
- /**
- * Handles a warning.
- *
- * If a PreprocessorListener is installed, it receives the
- * warning. Otherwise, an exception is thrown.
- */
- protected void warning(final int line, final int column, @Nonnull final String msg)
- throws LexerException {
- if (warnings.contains(Warning.ERROR))
- error(line, column, msg);
- else if (listener != null)
- listener.handleWarning(source, line, column, msg);
- else
- throw new LexerException("Warning at " + line + ":" + column + ": " + msg);
- }
-
- /**
- * Handles a warning.
- *
- * If a PreprocessorListener is installed, it receives the
- * warning. Otherwise, an exception is thrown.
- *
- * @see #warning(int, int, String)
- */
- protected void warning(@Nonnull final Token tok, @Nonnull final String msg)
- throws LexerException {
- warning(tok.getLine(), tok.getColumn(), msg);
- }
-
- /**
- * Adds a Macro to this Preprocessor.
- *
- * The given {@link Macro} object encapsulates both the name
- * and the expansion.
- * @throws IOException
- */
- public void addMacro(@Nonnull final Macro m) throws LexerException, IOException {
- // System.out.println("Macro " + m);
- final String name = m.getName();
- /* Already handled as a source error in macro(). */
- if ("defined".equals(name))
- throw new LexerException("Cannot redefine name 'defined'");
-
- if ( isActive() && null != source && !source.isExpanding(m) ) {
- m.setTokens( expand( m.getTokens() ) );
- }
- macros.put(m.getName(), m);
- }
-
- /**
- * Defines the given name as a macro.
- *
- * The String value is lexed into a token stream, which is
- * used as the macro expansion.
- */
- public void addMacro(@Nonnull final String name, @Nonnull final String value)
- throws LexerException {
- try {
- final Macro m = new Macro(name);
- final StringLexerSource s = new StringLexerSource(value);
- for (;;) {
- final Token tok = s.token();
- if (tok.getType() == EOF)
- break;
- m.addToken(tok);
- }
- addMacro(m);
- } catch (final IOException e) {
- throw new LexerException(e);
- }
- }
-
- /**
- * Defines the given name as a macro, with the value <code>1</code>.
- *
- * This is a convnience method, and is equivalent to
- * <code>addMacro(name, "1")</code>.
- */
- public void addMacro(@Nonnull final String name)
- throws LexerException {
- addMacro(name, "1");
- }
-
- /**
- * Sets the user include path used by this Preprocessor.
- */
- /* Note for future: Create an IncludeHandler? */
- public void setQuoteIncludePath(@Nonnull final List<String> path) {
- this.quoteincludepath = path;
- }
-
- /**
- * Returns the user include-path of this Preprocessor.
- *
- * This list may be freely modified by user code.
- */
- @Nonnull
- public List<String> getQuoteIncludePath() {
- return quoteincludepath;
- }
-
- /**
- * Sets the system include path used by this Preprocessor.
- */
- /* Note for future: Create an IncludeHandler? */
- public void setSystemIncludePath(@Nonnull final List<String> path) {
- this.sysincludepath = path;
- }
-
- /**
- * Returns the system include-path of this Preprocessor.
- *
- * This list may be freely modified by user code.
- */
- @Nonnull
- public List<String> getSystemIncludePath() {
- return sysincludepath;
- }
-
- /**
- * Sets the Objective-C frameworks path used by this Preprocessor.
- */
- /* Note for future: Create an IncludeHandler? */
- public void setFrameworksPath(@Nonnull final List<String> path) {
- this.frameworkspath = path;
- }
-
- /**
- * Returns the Objective-C frameworks path used by this
- * Preprocessor.
- *
- * This list may be freely modified by user code.
- */
- @Nonnull
- public List<String> getFrameworksPath() {
- return frameworkspath;
- }
-
- /**
- * Returns the Map of Macros parsed during the run of this
- * Preprocessor.
- */
- @Nonnull
- public Map<String, Macro> getMacros() {
- return macros;
- }
-
- /**
- * Returns the named macro.
- *
- * While you can modify the returned object, unexpected things
- * might happen if you do.
- */
- @CheckForNull
- public Macro getMacro(final String name) {
- return macros.get(name);
- }
-
- /**
- * Returns the list of {@link VirtualFile VirtualFiles} which have been
- * included by this Preprocessor.
- *
- * This does not include any {@link Source} provided to the constructor
- * or {@link #addInput(java.io.File)} or {@link #addInput(Source)}.
- */
- @Nonnull
- public List<? extends VirtualFile> getIncludes() {
- return includes;
- }
-
- /* States */
- private void push_state() {
- final State top = states.peek();
- states.push(new State(top));
- }
-
- private void pop_state()
- throws LexerException {
- final State s = states.pop();
- if (states.isEmpty()) {
- error(0, 0, "#" + "endif without #" + "if");
- states.push(s);
- }
- }
-
- private boolean isActive() {
- final State state = states.peek();
- return state.isParentActive() && state.isActive();
- }
-
-
- /* Sources */
- /**
- * Returns the top Source on the input stack.
- *
- * @see Source
- * @see #push_source(Source,boolean)
- * @see #pop_source()
- */
- // @CheckForNull
- public Source getSource() {
- return source;
- }
-
- /**
- * Pushes a Source onto the input stack.
- *
- * @see #getSource()
- * @see #pop_source()
- */
- protected void push_source(@Nonnull final Source source, final boolean autopop) {
- source.init(this);
- source.setParent(this.source, autopop);
- // source.setListener(listener);
- if (listener != null)
- listener.handleSourceChange(this.source, SourceChangeEvent.SUSPEND);
- this.source = source;
- if (listener != null)
- listener.handleSourceChange(this.source, SourceChangeEvent.PUSH);
- }
-
- /**
- * Pops a Source from the input stack.
- *
- * @see #getSource()
- * @see #push_source(Source,boolean)
- */
- @CheckForNull
- protected Token pop_source(final boolean linemarker)
- throws IOException {
- if (listener != null)
- listener.handleSourceChange(this.source, SourceChangeEvent.POP);
- final Source s = this.source;
- this.source = s.getParent();
- /* Always a noop unless called externally. */
- s.close();
- if (listener != null && this.source != null)
- listener.handleSourceChange(this.source, SourceChangeEvent.RESUME);
-
- final Source t = getSource();
- if (getFeature(Feature.LINEMARKERS)
- && s.isNumbered()
- && t != null) {
- /* We actually want 'did the nested source
- * contain a newline token', which isNumbered()
- * approximates. This is not perfect, but works.
- * FIXME: Removed the '+ 1', since all lines were off by one.
- * This solves this case, but I don't know _why_ this was here in the first place.
- */
- return line_token(t.getLine() /* SEE ABOVE: + 1 */, t.getName(), " 2");
- }
-
- return null;
- }
-
- protected void pop_source()
- throws IOException {
- pop_source(false);
- }
-
- @Nonnull
- private Token next_source() {
- if (inputs.isEmpty())
- return new Token(EOF);
- final Source s = inputs.remove(0);
- push_source(s, true);
- return line_token(s.getLine(), s.getName(), " 1");
- }
-
- /* Source tokens */
- private Token source_token;
-
- /* XXX Make this include the NL, and make all cpp directives eat
- * their own NL. */
- @Nonnull
- private Token line_token(final int line, @CheckForNull final String name, @Nonnull final String extra) {
- final StringBuilder buf = new StringBuilder();
- buf.append("#line ").append(line)
- .append(" \"");
- /* XXX This call to escape(name) is correct but ugly. */
- if (name == null)
- buf.append("<no file>");
- else
- MacroTokenSource.escape(buf, name);
- buf.append("\"").append(extra).append("\n");
- return new Token(P_LINE, line, 0, buf.toString(), null);
- }
-
- @Nonnull
- private Token source_token()
- throws IOException,
- LexerException {
- if (source_token != null) {
- final Token tok = source_token;
- source_token = null;
- if (getFeature(Feature.DEBUG))
- LOG.debug("Returning unget token " + tok);
- return tok;
- }
-
- for (;;) {
- final Source s = getSource();
- if (s == null) {
- final Token t = next_source();
- if (t.getType() == P_LINE && !getFeature(Feature.LINEMARKERS))
- continue;
- return t;
- }
- final Token tok = s.token();
- /* XXX Refactor with skipline() */
- if (tok.getType() == EOF && s.isAutopop()) {
- // System.out.println("Autopop " + s);
- final Token mark = pop_source(true);
- if (mark != null)
- return mark;
- continue;
- }
- if (getFeature(Feature.DEBUG))
- LOG.debug("Returning fresh token " + tok);
- return tok;
- }
- }
-
- private void source_untoken(final Token tok) {
- if (this.source_token != null)
- throw new IllegalStateException("Cannot return two tokens");
- this.source_token = tok;
- }
-
- private boolean isWhite(final Token tok) {
- final int type = tok.getType();
- return (type == WHITESPACE)
- || (type == CCOMMENT)
- || (type == CPPCOMMENT);
- }
-
- private Token source_token_nonwhite()
- throws IOException,
- LexerException {
- Token tok;
- do {
- tok = source_token();
- } while (isWhite(tok));
- return tok;
- }
-
- /**
- * Returns an NL or an EOF token.
- *
- * The metadata on the token will be correct, which is better
- * than generating a new one.
- *
- * This method can, as of recent patches, return a P_LINE token.
- */
- private Token source_skipline(final boolean white)
- throws IOException,
- LexerException {
- // (new Exception("skipping line")).printStackTrace(System.out);
- final Source s = getSource();
- final Token tok = s.skipline(white);
- /* XXX Refactor with source_token() */
- if (tok.getType() == EOF && s.isAutopop()) {
- // System.out.println("Autopop " + s);
- final Token mark = pop_source(true);
- if (mark != null)
- return mark;
- }
- return tok;
- }
-
- /* processes and expands a macro. */
- private boolean macro(final Macro m, final Token orig)
- throws IOException,
- LexerException {
- Token tok;
- List<Argument> args;
-
- // System.out.println("pp: expanding " + m);
- if (m.isFunctionLike()) {
- OPEN:
- for (;;) {
- tok = source_token();
- // System.out.println("pp: open: token is " + tok);
- switch (tok.getType()) {
- case WHITESPACE: /* XXX Really? */
-
- case CCOMMENT:
- case CPPCOMMENT:
- case NL:
- break; /* continue */
-
- case '(':
- break OPEN;
- default:
- source_untoken(tok);
- return false;
- }
- }
-
- // tok = expanded_token_nonwhite();
- tok = source_token_nonwhite();
-
- /* We either have, or we should have args.
- * This deals elegantly with the case that we have
- * one empty arg. */
- if (tok.getType() != ')' || m.getArgs() > 0) {
- args = new ArrayList<Argument>();
-
- Argument arg = new Argument();
- int depth = 0;
- boolean space = false;
-
- ARGS:
- for (;;) {
- // System.out.println("pp: arg: token is " + tok);
- switch (tok.getType()) {
- case EOF:
- error(tok, "EOF in macro args");
- return false;
-
- case ',':
- if (depth == 0) {
- if (m.isVariadic()
- && /* We are building the last arg. */ args.size() == m.getArgs() - 1) {
- /* Just add the comma. */
- arg.addToken(tok);
- } else {
- args.add(arg);
- arg = new Argument();
- }
- } else {
- arg.addToken(tok);
- }
- space = false;
- break;
- case ')':
- if (depth == 0) {
- args.add(arg);
- break ARGS;
- } else {
- depth--;
- arg.addToken(tok);
- }
- space = false;
- break;
- case '(':
- depth++;
- arg.addToken(tok);
- space = false;
- break;
-
- case WHITESPACE:
- case CCOMMENT:
- case CPPCOMMENT:
- case NL:
- /* Avoid duplicating spaces. */
- space = true;
- break;
-
- default:
- /* Do not put space on the beginning of
- * an argument token. */
- if (space && !arg.isEmpty())
- arg.addToken(Token.space);
- arg.addToken(tok);
- space = false;
- break;
-
- }
- // tok = expanded_token();
- tok = source_token();
- }
- /* space may still be true here, thus trailing space
- * is stripped from arguments. */
-
- if (args.size() != m.getArgs()) {
- if (m.isVariadic()) {
- if (args.size() == m.getArgs() - 1) {
- args.add(new Argument());
- } else {
- error(tok,
- "variadic macro " + m.getName()
- + " has at least " + (m.getArgs() - 1) + " parameters "
- + "but given " + args.size() + " args");
- return false;
- }
- } else {
- error(tok,
- "macro " + m.getName()
- + " has " + m.getArgs() + " parameters "
- + "but given " + args.size() + " args");
- /* We could replay the arg tokens, but I
- * note that GNU cpp does exactly what we do,
- * i.e. output the macro name and chew the args.
- */
- return false;
- }
- }
-
- for (final Argument a : args) {
- a.expand(this);
- }
-
- // System.out.println("Macro " + m + " args " + args);
- } else {
- /* nargs == 0 and we (correctly) got () */
- args = null;
- }
-
- } else {
- /* Macro without args. */
- args = null;
- }
-
- if (m == __LINE__) {
- push_source(new FixedTokenSource(
- new Token[]{new Token(NUMBER,
- orig.getLine(), orig.getColumn(),
- Integer.toString(orig.getLine()),
- new NumericValue(10, Integer.toString(orig.getLine())))}
- ), true);
- } else if (m == __FILE__) {
- final StringBuilder buf = new StringBuilder("\"");
- String name = getSource().getName();
- if (name == null)
- name = "<no file>";
- for (int i = 0; i < name.length(); i++) {
- final char c = name.charAt(i);
- switch (c) {
- case '\\':
- buf.append("\\\\");
- break;
- case '"':
- buf.append("\\\"");
- break;
- default:
- buf.append(c);
- break;
- }
- }
- buf.append("\"");
- final String text = buf.toString();
- push_source(new FixedTokenSource(
- new Token[]{new Token(STRING,
- orig.getLine(), orig.getColumn(),
- text, text)}
- ), true);
- } else if (m == __COUNTER__) {
- /* This could equivalently have been done by adding
- * a special Macro subclass which overrides getTokens(). */
- final int value = this.counter++;
- push_source(new FixedTokenSource(
- new Token[]{new Token(NUMBER,
- orig.getLine(), orig.getColumn(),
- Integer.toString(value),
- new NumericValue(10, Integer.toString(value)))}
- ), true);
- } else {
- push_source(new MacroTokenSource(m, args), true);
- }
-
- return true;
- }
-
- /**
- * Expands an argument.
- */
- /* I'd rather this were done lazily, but doing so breaks spec. */
- @Nonnull
- /* pp */ List<Token> expand(@Nonnull final List<Token> arg)
- throws IOException,
- LexerException {
- final List<Token> expansion = new ArrayList<Token>();
- boolean space = false;
-
- push_source(new FixedTokenSource(arg), false);
-
- EXPANSION:
- for (;;) {
- final Token tok = expanded_token();
- switch (tok.getType()) {
- case EOF:
- break EXPANSION;
-
- case WHITESPACE:
- case CCOMMENT:
- case CPPCOMMENT:
- space = true;
- break;
-
- default:
- if (space && !expansion.isEmpty())
- expansion.add(Token.space);
- expansion.add(tok);
- space = false;
- break;
- }
- }
-
- // Always returns null.
- pop_source(false);
-
- return expansion;
- }
-
- /* processes a #define directive */
- private Token define()
- throws IOException,
- LexerException {
- Token tok = source_token_nonwhite();
- if (tok.getType() != IDENTIFIER) {
- error(tok, "Expected identifier");
- return source_skipline(false);
- }
- /* if predefined */
- final String name = tok.getText();
- if ("defined".equals(name)) {
- error(tok, "Cannot redefine name 'defined'");
- return source_skipline(false);
- }
-
- final Macro m = new Macro(getSource(), name);
- List<String> args;
-
- tok = source_token();
- if (tok.getType() == '(') {
- tok = source_token_nonwhite();
- if (tok.getType() != ')') {
- args = new ArrayList<String>();
- ARGS:
- for (;;) {
- switch (tok.getType()) {
- case IDENTIFIER:
- args.add(tok.getText());
- break;
- case ELLIPSIS:
- // Unnamed Variadic macro
- args.add("__VA_ARGS__");
- // We just named the ellipsis, but we unget the token
- // to allow the ELLIPSIS handling below to process it.
- source_untoken(tok);
- break;
- case NL:
- case EOF:
- error(tok,
- "Unterminated macro parameter list");
- return tok;
- default:
- error(tok,
- "error in macro parameters: "
- + tok.getText());
- return source_skipline(false);
- }
- tok = source_token_nonwhite();
- switch (tok.getType()) {
- case ',':
- break;
- case ELLIPSIS:
- tok = source_token_nonwhite();
- if (tok.getType() != ')')
- error(tok,
- "ellipsis must be on last argument");
- m.setVariadic(true);
- break ARGS;
- case ')':
- break ARGS;
-
- case NL:
- case EOF:
- /* Do not skip line. */
- error(tok,
- "Unterminated macro parameters");
- return tok;
- default:
- error(tok,
- "Bad token in macro parameters: "
- + tok.getText());
- return source_skipline(false);
- }
- tok = source_token_nonwhite();
- }
- } else {
- assert tok.getType() == ')' : "Expected ')'";
- args = Collections.emptyList();
- }
-
- m.setArgs(args);
- } else {
- /* For searching. */
- args = Collections.emptyList();
- source_untoken(tok);
- }
-
- /* Get an expansion for the macro, using indexOf. */
- boolean space = false;
- boolean paste = false;
- int idx;
-
- /* Ensure no space at start. */
- tok = source_token_nonwhite();
- EXPANSION:
- for (;;) {
- switch (tok.getType()) {
- case EOF:
- break EXPANSION;
- case NL:
- break EXPANSION;
-
- case CCOMMENT:
- case CPPCOMMENT:
- /* XXX This is where we implement GNU's cpp -CC. */
- // break;
- case WHITESPACE:
- if (!paste)
- space = true;
- break;
-
- /* Paste. */
- case PASTE:
- space = false;
- paste = true;
- m.addPaste(new Token(M_PASTE,
- tok.getLine(), tok.getColumn(),
- "#" + "#", null));
- break;
-
- /* Stringify. */
- case '#':
- if (space)
- m.addToken(Token.space);
- space = false;
- final Token la = source_token_nonwhite();
- if (la.getType() == IDENTIFIER
- && ((idx = args.indexOf(la.getText())) != -1)) {
- m.addToken(new Token(M_STRING,
- la.getLine(), la.getColumn(),
- "#" + la.getText(),
- Integer.valueOf(idx)));
- } else {
- m.addToken(tok);
- /* Allow for special processing. */
- source_untoken(la);
- }
- break;
-
- case IDENTIFIER:
- if (space)
- m.addToken(Token.space);
- space = false;
- paste = false;
- idx = args.indexOf(tok.getText());
- if (idx == -1)
- m.addToken(tok);
- else
- m.addToken(new Token(M_ARG,
- tok.getLine(), tok.getColumn(),
- tok.getText(),
- Integer.valueOf(idx)));
- break;
-
- default:
- if (space)
- m.addToken(Token.space);
- space = false;
- paste = false;
- m.addToken(tok);
- break;
- }
- tok = source_token();
- }
-
- if (getFeature(Feature.DEBUG))
- LOG.debug("Defined macro " + m);
- addMacro(m);
-
- return tok; /* NL or EOF. */
-
- }
-
- @Nonnull
- private Token undef()
- throws IOException,
- LexerException {
- final Token tok = source_token_nonwhite();
- if (tok.getType() != IDENTIFIER) {
- error(tok,
- "Expected identifier, not " + tok.getText());
- if (tok.getType() == NL || tok.getType() == EOF)
- return tok;
- } else {
- final Macro m = getMacro(tok.getText());
- if (m != null) {
- /* XXX error if predefined */
- macros.remove(m.getName());
- }
- }
- return source_skipline(true);
- }
-
- /**
- * Attempts to include the given file.
- *
- * User code may override this method to implement a virtual
- * file system.
- */
- protected boolean include(@Nonnull final VirtualFile file)
- throws IOException,
- LexerException {
- // System.out.println("Try to include " + ((File)file).getAbsolutePath());
- if (!file.isFile())
- return false;
- if (getFeature(Feature.DEBUG))
- LOG.debug("pp: including " + file);
- includes.add(file);
- push_source(file.getSource(), true);
- return true;
- }
-
- /**
- * Includes a file from an include path, by name.
- */
- protected boolean include(@Nonnull final Iterable<String> path, @Nonnull final String name)
- throws IOException,
- LexerException {
- for (final String dir : path) {
- final VirtualFile file = getFileSystem().getFile(dir, name);
- if (include(file))
- return true;
- }
- return false;
- }
-
- /**
- * Handles an include directive.
- */
- private void include(
- @CheckForNull final String parent, final int line,
- @Nonnull final String name, final boolean quoted, final boolean next)
- throws IOException,
- LexerException {
- if (name.startsWith("/")) {
- final VirtualFile file = filesystem.getFile(name);
- if (include(file))
- return;
- final StringBuilder buf = new StringBuilder();
- buf.append("File not found: ").append(name);
- error(line, 0, buf.toString());
- return;
- }
-
- VirtualFile pdir = null;
- if (quoted) {
- if (parent != null) {
- final VirtualFile pfile = filesystem.getFile(parent);
- pdir = pfile.getParentFile();
- }
- if (pdir != null) {
- final VirtualFile ifile = pdir.getChildFile(name);
- if (include(ifile))
- return;
- }
- if (include(quoteincludepath, name))
- return;
- } else {
- final int idx = name.indexOf('/');
- if (idx != -1) {
- final String frameworkName = name.substring(0, idx);
- final String headerName = name.substring(idx + 1);
- final String headerPath = frameworkName + ".framework/Headers/" + headerName;
- if (include(frameworkspath, headerPath))
- return;
- }
- }
-
- if (include(sysincludepath, name))
- return;
-
- final StringBuilder buf = new StringBuilder();
- buf.append("File not found: ").append(name);
- buf.append(" in");
- if (quoted) {
- buf.append(" .").append('(').append(pdir).append(')');
- for (final String dir : quoteincludepath)
- buf.append(" ").append(dir);
- }
- for (final String dir : sysincludepath)
- buf.append(" ").append(dir);
- error(line, 0, buf.toString());
- }
-
- @Nonnull
- private Token include(final boolean next)
- throws IOException,
- LexerException {
- final LexerSource lexer = (LexerSource) source;
- try {
- lexer.setInclude(true);
- Token tok = token_nonwhite();
-
- String name;
- boolean quoted;
-
- if (tok.getType() == STRING) {
- /* XXX Use the original text, not the value.
- * Backslashes must not be treated as escapes here. */
- final StringBuilder buf = new StringBuilder((String) tok.getValue());
- HEADER:
- for (;;) {
- tok = token_nonwhite();
- switch (tok.getType()) {
- case STRING:
- buf.append((String) tok.getValue());
- break;
- case NL:
- case EOF:
- break HEADER;
- default:
- warning(tok,
- "Unexpected token on #" + "include line");
- return source_skipline(false);
- }
- }
- name = buf.toString();
- quoted = true;
- } else if (tok.getType() == HEADER) {
- name = (String) tok.getValue();
- quoted = false;
- tok = source_skipline(true);
- } else {
- error(tok,
- "Expected string or header, not " + tok.getText());
- switch (tok.getType()) {
- case NL:
- case EOF:
- return tok;
- default:
- /* Only if not a NL or EOF already. */
- return source_skipline(false);
- }
- }
-
- /* Do the inclusion. */
- include(source.getPath(), tok.getLine(), name, quoted, next);
-
- /* 'tok' is the 'nl' after the include. We use it after the
- * #line directive. */
- if (getFeature(Feature.LINEMARKERS))
- return line_token(1, source.getName(), " 1");
- return tok;
- } finally {
- lexer.setInclude(false);
- }
- }
-
- protected void pragma_once(@Nonnull final Token name)
- throws IOException, LexerException {
- final Source s = this.source;
- if (!onceseenpaths.add(s.getPath())) {
- final Token mark = pop_source(true);
- // FixedTokenSource should never generate a linemarker on exit.
- if (mark != null)
- push_source(new FixedTokenSource(Arrays.asList(mark)), true);
- }
- }
-
- protected void pragma(@Nonnull final Token name, @Nonnull final List<Token> value)
- throws IOException,
- LexerException {
- if (getFeature(Feature.PRAGMA_ONCE)) {
- if ("once".equals(name.getText())) {
- pragma_once(name);
- return;
- }
- }
- warning(name, "Unknown #" + "pragma: " + name.getText());
- }
-
- @Nonnull
- private Token pragma()
- throws IOException,
- LexerException {
- Token name;
-
- NAME:
- for (;;) {
- final Token tok = token();
- switch (tok.getType()) {
- case EOF:
- /* There ought to be a newline before EOF.
- * At least, in any skipline context. */
- /* XXX Are we sure about this? */
- warning(tok,
- "End of file in #" + "pragma");
- return tok;
- case NL:
- /* This may contain one or more newlines. */
- warning(tok,
- "Empty #" + "pragma");
- return tok;
- case CCOMMENT:
- case CPPCOMMENT:
- case WHITESPACE:
- continue NAME;
- case IDENTIFIER:
- name = tok;
- break NAME;
- default:
- return source_skipline(false);
- }
- }
-
- Token tok;
- final List<Token> value = new ArrayList<Token>();
- VALUE:
- for (;;) {
- tok = token();
- switch (tok.getType()) {
- case EOF:
- /* There ought to be a newline before EOF.
- * At least, in any skipline context. */
- /* XXX Are we sure about this? */
- warning(tok,
- "End of file in #" + "pragma");
- break VALUE;
- case NL:
- /* This may contain one or more newlines. */
- break VALUE;
- case CCOMMENT:
- case CPPCOMMENT:
- break;
- case WHITESPACE:
- value.add(tok);
- break;
- default:
- value.add(tok);
- break;
- }
- }
-
- pragma(name, value);
-
- return tok; /* The NL. */
-
- }
-
- /* For #error and #warning. */
- private void error(@Nonnull final Token pptok, final boolean is_error)
- throws IOException,
- LexerException {
- final StringBuilder buf = new StringBuilder();
- buf.append('#').append(pptok.getText()).append(' ');
- /* Peculiar construction to ditch first whitespace. */
- Token tok = source_token_nonwhite();
- ERROR:
- for (;;) {
- switch (tok.getType()) {
- case NL:
- case EOF:
- break ERROR;
- default:
- buf.append(tok.getText());
- break;
- }
- tok = source_token();
- }
- if (is_error)
- error(pptok, buf.toString());
- else
- warning(pptok, buf.toString());
- }
-
- /* This bypasses token() for #elif expressions.
- * If we don't do this, then isActive() == false
- * causes token() to simply chew the entire input line. */
- @Nonnull
- private Token expanded_token()
- throws IOException,
- LexerException {
- for (;;) {
- final Token tok = source_token();
- // System.out.println("Source token is " + tok);
- if (tok.getType() == IDENTIFIER) {
- final Macro m = getMacro(tok.getText());
- if (m == null)
- return tok;
- if (source.isExpanding(m))
- return tok;
- if (macro(m, tok))
- continue;
- }
- return tok;
- }
- }
-
- @Nonnull
- private Token expanded_token_nonwhite()
- throws IOException,
- LexerException {
- Token tok;
- do {
- tok = expanded_token();
- // System.out.println("expanded token is " + tok);
- } while (isWhite(tok));
- return tok;
- }
-
- @CheckForNull
- private Token expr_token = null;
-
- @Nonnull
- private Token expr_token()
- throws IOException,
- LexerException {
- Token tok = expr_token;
-
- if (tok != null) {
- // System.out.println("ungetting");
- expr_token = null;
- } else {
- tok = expanded_token_nonwhite();
- // System.out.println("expt is " + tok);
-
- if (tok.getType() == IDENTIFIER
- && tok.getText().equals("defined")) {
- Token la = source_token_nonwhite();
- boolean paren = false;
- if (la.getType() == '(') {
- paren = true;
- la = source_token_nonwhite();
- }
-
- // System.out.println("Core token is " + la);
- if (la.getType() != IDENTIFIER) {
- error(la,
- "defined() needs identifier, not "
- + la.getText());
- tok = new Token(NUMBER,
- la.getLine(), la.getColumn(),
- "0", new NumericValue(10, "0"));
- } else if (macros.containsKey(la.getText())) {
- // System.out.println("Found macro");
- tok = new Token(NUMBER,
- la.getLine(), la.getColumn(),
- "1", new NumericValue(10, "1"));
- } else {
- // System.out.println("Not found macro");
- tok = new Token(NUMBER,
- la.getLine(), la.getColumn(),
- "0", new NumericValue(10, "0"));
- }
-
- if (paren) {
- la = source_token_nonwhite();
- if (la.getType() != ')') {
- expr_untoken(la);
- error(la, "Missing ) in defined(). Got " + la.getText());
- }
- }
- }
- }
-
- // System.out.println("expr_token returns " + tok);
- return tok;
- }
-
- private void expr_untoken(@Nonnull final Token tok)
- throws LexerException {
- if (expr_token != null)
- throw new InternalException(
- "Cannot unget two expression tokens."
- );
- expr_token = tok;
- }
-
- private int expr_priority(@Nonnull final Token op) {
- switch (op.getType()) {
- case '/':
- return 11;
- case '%':
- return 11;
- case '*':
- return 11;
- case '+':
- return 10;
- case '-':
- return 10;
- case LSH:
- return 9;
- case RSH:
- return 9;
- case '<':
- return 8;
- case '>':
- return 8;
- case LE:
- return 8;
- case GE:
- return 8;
- case EQ:
- return 7;
- case NE:
- return 7;
- case '&':
- return 6;
- case '^':
- return 5;
- case '|':
- return 4;
- case LAND:
- return 3;
- case LOR:
- return 2;
- case '?':
- return 1;
- default:
- // System.out.println("Unrecognised operator " + op);
- return 0;
- }
- }
-
- private long expr(final int priority)
- throws IOException,
- LexerException {
- /*
- * (new Exception("expr(" + priority + ") called")).printStackTrace();
- */
-
- Token tok = expr_token();
- long lhs, rhs;
-
- // System.out.println("Expr lhs token is " + tok);
- switch (tok.getType()) {
- case '(':
- lhs = expr(0);
- tok = expr_token();
- if (tok.getType() != ')') {
- expr_untoken(tok);
- error(tok, "Missing ) in expression. Got " + tok.getText());
- return 0;
- }
- break;
-
- case '~':
- lhs = ~expr(11);
- break;
- case '!':
- lhs = expr(11) == 0 ? 1 : 0;
- break;
- case '-':
- lhs = -expr(11);
- break;
- case NUMBER:
- final NumericValue value = (NumericValue) tok.getValue();
- lhs = value.longValue();
- break;
- case CHARACTER:
- lhs = ((Character) tok.getValue()).charValue();
- break;
- case IDENTIFIER:
- if (warnings.contains(Warning.UNDEF))
- warning(tok, "Undefined token '" + tok.getText()
- + "' encountered in conditional.");
- lhs = 0;
- break;
-
- default:
- expr_untoken(tok);
- error(tok,
- "Bad token in expression: " + tok.getText());
- return 0;
- }
-
- EXPR:
- for (;;) {
- // System.out.println("expr: lhs is " + lhs + ", pri = " + priority);
- final Token op = expr_token();
- final int pri = expr_priority(op); /* 0 if not a binop. */
-
- if (pri == 0 || priority >= pri) {
- expr_untoken(op);
- break EXPR;
- }
- rhs = expr(pri);
- // System.out.println("rhs token is " + rhs);
- switch (op.getType()) {
- case '/':
- if (rhs == 0) {
- error(op, "Division by zero");
- lhs = 0;
- } else {
- lhs = lhs / rhs;
- }
- break;
- case '%':
- if (rhs == 0) {
- error(op, "Modulus by zero");
- lhs = 0;
- } else {
- lhs = lhs % rhs;
- }
- break;
- case '*':
- lhs = lhs * rhs;
- break;
- case '+':
- lhs = lhs + rhs;
- break;
- case '-':
- lhs = lhs - rhs;
- break;
- case '<':
- lhs = lhs < rhs ? 1 : 0;
- break;
- case '>':
- lhs = lhs > rhs ? 1 : 0;
- break;
- case '&':
- lhs = lhs & rhs;
- break;
- case '^':
- lhs = lhs ^ rhs;
- break;
- case '|':
- lhs = lhs | rhs;
- break;
-
- case LSH:
- lhs = lhs << rhs;
- break;
- case RSH:
- lhs = lhs >> rhs;
- break;
- case LE:
- lhs = lhs <= rhs ? 1 : 0;
- break;
- case GE:
- lhs = lhs >= rhs ? 1 : 0;
- break;
- case EQ:
- lhs = lhs == rhs ? 1 : 0;
- break;
- case NE:
- lhs = lhs != rhs ? 1 : 0;
- break;
- case LAND:
- lhs = (lhs != 0) && (rhs != 0) ? 1 : 0;
- break;
- case LOR:
- lhs = (lhs != 0) || (rhs != 0) ? 1 : 0;
- break;
-
- case '?': {
- tok = expr_token();
- if (tok.getType() != ':') {
- expr_untoken(tok);
- error(tok, "Missing : in conditional expression. Got " + tok.getText());
- return 0;
- }
- final long falseResult = expr(0);
- lhs = (lhs != 0) ? rhs : falseResult;
- }
- break;
-
- default:
- error(op,
- "Unexpected operator " + op.getText());
- return 0;
-
- }
- }
-
- /*
- * (new Exception("expr returning " + lhs)).printStackTrace();
- */
- // System.out.println("expr returning " + lhs);
- return lhs;
- }
-
- @Nonnull
- private Token toWhitespace(@Nonnull final Token tok) {
- final String text = tok.getText();
- final int len = text.length();
- boolean cr = false;
- int nls = 0;
-
- for (int i = 0; i < len; i++) {
- final char c = text.charAt(i);
-
- switch (c) {
- case '\r':
- cr = true;
- nls++;
- break;
- case '\n':
- if (cr) {
- cr = false;
- break;
- }
- /* fallthrough */
- case '\u2028':
- case '\u2029':
- case '\u000B':
- case '\u000C':
- case '\u0085':
- cr = false;
- nls++;
- break;
- }
- }
-
- final char[] cbuf = new char[nls];
- Arrays.fill(cbuf, '\n');
- return new Token(WHITESPACE,
- tok.getLine(), tok.getColumn(),
- new String(cbuf));
- }
-
- @Nonnull
- private Token _token()
- throws IOException,
- LexerException {
-
- for (;;) {
- Token tok;
- if (!isActive()) {
- final Source s = getSource();
- if (s == null) {
- final Token t = next_source();
- if (t.getType() == P_LINE && !getFeature(Feature.LINEMARKERS))
- continue;
- return t;
- }
-
- try {
- /* XXX Tell lexer to ignore warnings. */
- s.setActive(false);
- tok = source_token();
- } finally {
- /* XXX Tell lexer to stop ignoring warnings. */
- s.setActive(true);
- }
- switch (tok.getType()) {
- case HASH:
- case NL:
- case EOF:
- /* The preprocessor has to take action here. */
- break;
- case WHITESPACE:
- return tok;
- case CCOMMENT:
- case CPPCOMMENT:
- // Patch up to preserve whitespace.
- if (getFeature(Feature.KEEPALLCOMMENTS))
- return tok;
- if (!isActive())
- return toWhitespace(tok);
- if (getFeature(Feature.KEEPCOMMENTS))
- return tok;
- return toWhitespace(tok);
- default:
- // Return NL to preserve whitespace.
- /* XXX This might lose a comment. */
- return source_skipline(false);
- }
- } else {
- tok = source_token();
- }
-
- LEX:
- switch (tok.getType()) {
- case EOF:
- /* Pop the stacks. */
- return tok;
-
- case WHITESPACE:
- case NL:
- return tok;
-
- case CCOMMENT:
- case CPPCOMMENT:
- return tok;
-
- case '!':
- case '%':
- case '&':
- case '(':
- case ')':
- case '*':
- case '+':
- case ',':
- case '-':
- case '/':
- case ':':
- case ';':
- case '<':
- case '=':
- case '>':
- case '?':
- case '[':
- case ']':
- case '^':
- case '{':
- case '|':
- case '}':
- case '~':
- case '.':
-
- /* From Olivier Chafik for Objective C? */
- case '@':
- /* The one remaining ASCII, might as well. */
- case '`':
-
- // case '#':
- case AND_EQ:
- case ARROW:
- case CHARACTER:
- case DEC:
- case DIV_EQ:
- case ELLIPSIS:
- case EQ:
- case GE:
- case HEADER: /* Should only arise from include() */
-
- case INC:
- case LAND:
- case LE:
- case LOR:
- case LSH:
- case LSH_EQ:
- case SUB_EQ:
- case MOD_EQ:
- case MULT_EQ:
- case NE:
- case OR_EQ:
- case PLUS_EQ:
- case RANGE:
- case RSH:
- case RSH_EQ:
- case STRING:
- case SQSTRING:
- case XOR_EQ:
- return tok;
-
- case NUMBER:
- return tok;
-
- case IDENTIFIER:
- final Macro m = getMacro(tok.getText());
- if (m == null)
- return tok;
- if (source.isExpanding(m))
- return tok;
- if (macro(m, tok))
- break;
- return tok;
-
- case P_LINE:
- if (getFeature(Feature.LINEMARKERS))
- return tok;
- break;
-
- case INVALID:
- if (getFeature(Feature.CSYNTAX))
- error(tok, String.valueOf(tok.getValue()));
- return tok;
-
- default:
- throw new InternalException("Bad token " + tok);
- // break;
-
- case HASH:
- tok = source_token_nonwhite();
- // (new Exception("here")).printStackTrace();
- switch (tok.getType()) {
- case NL:
- break LEX; /* Some code has #\n */
-
- case IDENTIFIER:
- break;
- default:
- error(tok,
- "Preprocessor directive not a word "
- + tok.getText());
- return source_skipline(false);
- }
- final PreprocessorCommand ppcmd = PreprocessorCommand.forText(tok.getText());
- if (ppcmd == null) {
- error(tok,
- "Unknown preprocessor directive "
- + tok.getText());
- return source_skipline(false);
- }
-
- PP:
- switch (ppcmd) {
-
- case PP_DEFINE:
- if (!isActive())
- return source_skipline(false);
- else
- return define();
- // break;
-
- case PP_UNDEF:
- if (!isActive())
- return source_skipline(false);
- else
- return undef();
- // break;
-
- case PP_INCLUDE:
- if (!isActive())
- return source_skipline(false);
- else
- return include(false);
- // break;
- case PP_INCLUDE_NEXT:
- if (!isActive())
- return source_skipline(false);
- if (!getFeature(Feature.INCLUDENEXT)) {
- error(tok,
- "Directive include_next not enabled"
- );
- return source_skipline(false);
- }
- return include(true);
- // break;
-
- case PP_WARNING:
- case PP_ERROR:
- if (!isActive())
- return source_skipline(false);
- else
- error(tok, ppcmd == PP_ERROR);
- break;
-
- case PP_IF:
- push_state();
- if (!isActive()) {
- return source_skipline(false);
- }
- expr_token = null;
- states.peek().setActive(expr(0) != 0);
- tok = expr_token(); /* unget */
-
- if (tok.getType() == NL)
- return tok;
- return source_skipline(true);
- // break;
-
- case PP_ELIF:
- State state = states.peek();
- if (false) {
- /* Check for 'if' */;
- } else if (state.sawElse()) {
- error(tok,
- "#elif after #" + "else");
- return source_skipline(false);
- } else if (!state.isParentActive()) {
- /* Nested in skipped 'if' */
- return source_skipline(false);
- } else if (state.isActive()) {
- /* The 'if' part got executed. */
- state.setParentActive(false);
- /* This is like # else # if but with
- * only one # end. */
- state.setActive(false);
- return source_skipline(false);
- } else {
- expr_token = null;
- state.setActive(expr(0) != 0);
- tok = expr_token(); /* unget */
-
- if (tok.getType() == NL)
- return tok;
- return source_skipline(true);
- }
- // break;
-
- case PP_ELSE:
- state = states.peek();
- if (false)
- /* Check for 'if' */ ; else if (state.sawElse()) {
- error(tok,
- "#" + "else after #" + "else");
- return source_skipline(false);
- } else {
- state.setSawElse();
- state.setActive(!state.isActive());
- return source_skipline(warnings.contains(Warning.ENDIF_LABELS));
- }
- // break;
-
- case PP_IFDEF:
- push_state();
- if (!isActive()) {
- return source_skipline(false);
- } else {
- tok = source_token_nonwhite();
- // System.out.println("ifdef " + tok);
- if (tok.getType() != IDENTIFIER) {
- error(tok,
- "Expected identifier, not "
- + tok.getText());
- return source_skipline(false);
- } else {
- final String text = tok.getText();
- final boolean exists
- = macros.containsKey(text);
- states.peek().setActive(exists);
- return source_skipline(true);
- }
- }
- // break;
-
- case PP_IFNDEF:
- push_state();
- if (!isActive()) {
- return source_skipline(false);
- } else {
- tok = source_token_nonwhite();
- if (tok.getType() != IDENTIFIER) {
- error(tok,
- "Expected identifier, not "
- + tok.getText());
- return source_skipline(false);
- } else {
- final String text = tok.getText();
- final boolean exists
- = macros.containsKey(text);
- states.peek().setActive(!exists);
- return source_skipline(true);
- }
- }
- // break;
-
- case PP_ENDIF:
- pop_state();
- return source_skipline(warnings.contains(Warning.ENDIF_LABELS));
- // break;
-
- case PP_LINE:
- return source_skipline(false);
- // break;
-
- case PP_PRAGMA:
- if (!isActive())
- return source_skipline(false);
- return pragma();
- // break;
-
- default:
- /* Actual unknown directives are
- * processed above. If we get here,
- * we succeeded the map lookup but
- * failed to handle it. Therefore,
- * this is (unconditionally?) fatal. */
- // if (isActive()) /* XXX Could be warning. */
- throw new InternalException(
- "Internal error: Unknown directive "
- + tok);
- // return source_skipline(false);
- }
-
- }
- }
- }
-
- @Nonnull
- private Token token_nonwhite()
- throws IOException,
- LexerException {
- Token tok;
- do {
- tok = _token();
- } while (isWhite(tok));
- return tok;
- }
-
- /**
- * Returns the next preprocessor token.
- *
- * @see Token
- * @throws LexerException if a preprocessing error occurs.
- * @throws InternalException if an unexpected error condition arises.
- */
- @Nonnull
- public Token token()
- throws IOException,
- LexerException {
- final Token tok = _token();
- if (getFeature(Feature.DEBUG))
- LOG.debug("pp: Returning " + tok);
- return tok;
- }
-
- @Override
- public String toString() {
- final StringBuilder buf = new StringBuilder();
-
- Source s = getSource();
- while (s != null) {
- buf.append(" -> ").append(String.valueOf(s)).append("\n");
- s = s.getParent();
- }
-
- final Map<String, Macro> macros = new TreeMap<String, Macro>(getMacros());
- for (final Macro macro : macros.values()) {
- buf.append("#").append("macro ").append(macro).append("\n");
- }
-
- return buf.toString();
- }
-
- @Override
- public void close()
- throws IOException {
- {
- Source s = source;
- while (s != null) {
- s.close();
- s = s.getParent();
- }
- }
- for (final Source s : inputs) {
- s.close();
- }
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/PreprocessorCommand.java b/src/main/java/org/anarres/cpp/PreprocessorCommand.java
deleted file mode 100644
index 3938360..0000000
--- a/src/main/java/org/anarres/cpp/PreprocessorCommand.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.anarres.cpp;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-/**
- *
- * @author shevek
- */
-public enum PreprocessorCommand {
-
- PP_DEFINE("define"),
- PP_ELIF("elif"),
- PP_ELSE("else"),
- PP_ENDIF("endif"),
- PP_ERROR("error"),
- PP_IF("if"),
- PP_IFDEF("ifdef"),
- PP_IFNDEF("ifndef"),
- PP_INCLUDE("include"),
- PP_LINE("line"),
- PP_PRAGMA("pragma"),
- PP_UNDEF("undef"),
- PP_WARNING("warning"),
- PP_INCLUDE_NEXT("include_next"),
- PP_IMPORT("import");
- private final String text;
- /* pp */ PreprocessorCommand(String text) {
- this.text = text;
- }
-
- @CheckForNull
- public static PreprocessorCommand forText(@Nonnull String text) {
- for (PreprocessorCommand ppcmd : PreprocessorCommand.values())
- if (ppcmd.text.equals(text))
- return ppcmd;
- return null;
- }
-}
diff --git a/src/main/java/org/anarres/cpp/PreprocessorListener.java b/src/main/java/org/anarres/cpp/PreprocessorListener.java
deleted file mode 100644
index 0d3f7fc..0000000
--- a/src/main/java/org/anarres/cpp/PreprocessorListener.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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 javax.annotation.Nonnull;
-
-/**
- * A handler for preprocessor events, primarily errors and warnings.
- *
- * If no PreprocessorListener is installed in a Preprocessor, all
- * error and warning events will throw an exception. Installing a
- * listener allows more intelligent handling of these events.
- */
-public interface PreprocessorListener {
-
- /**
- * Handles a warning.
- *
- * The behaviour of this method is defined by the
- * implementation. It may simply record the error message, or
- * it may throw an exception.
- */
- public void handleWarning(@Nonnull Source source, int line, int column,
- @Nonnull String msg)
- throws LexerException;
-
- /**
- * Handles an error.
- *
- * The behaviour of this method is defined by the
- * implementation. It may simply record the error message, or
- * it may throw an exception.
- */
- public void handleError(@Nonnull Source source, int line, int column,
- @Nonnull String msg)
- throws LexerException;
-
- public enum SourceChangeEvent {
-
- SUSPEND, PUSH, POP, RESUME;
- }
-
- public void handleSourceChange(@Nonnull Source source, @Nonnull SourceChangeEvent event);
-
-}
diff --git a/src/main/java/org/anarres/cpp/ResourceFileSystem.java b/src/main/java/org/anarres/cpp/ResourceFileSystem.java
deleted file mode 100644
index 7efd664..0000000
--- a/src/main/java/org/anarres/cpp/ResourceFileSystem.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.anarres.cpp;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import javax.annotation.Nonnull;
-
-/**
- *
- * @author shevek
- */
-public class ResourceFileSystem implements VirtualFileSystem {
-
- private final ClassLoader loader;
-
- public ResourceFileSystem(@Nonnull ClassLoader loader) {
- this.loader = loader;
- }
-
- @Override
- public VirtualFile getFile(String path) {
- return new ResourceFile(loader, path);
- }
-
- @Override
- public VirtualFile getFile(String dir, String name) {
- return getFile(dir + "/" + name);
- }
-
- private class ResourceFile implements VirtualFile {
-
- private final ClassLoader loader;
- private final String path;
-
- public ResourceFile(ClassLoader loader, String path) {
- this.loader = loader;
- this.path = path;
- }
-
- @Override
- public boolean isFile() {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
-
- @Override
- public String getPath() {
- return path;
- }
-
- @Override
- public String getName() {
- return path.substring(path.lastIndexOf('/') + 1);
- }
-
- @Override
- public ResourceFile getParentFile() {
- int idx = path.lastIndexOf('/');
- if (idx < 1)
- return null;
- return new ResourceFile(loader, path.substring(0, idx));
- }
-
- @Override
- public ResourceFile getChildFile(String name) {
- return new ResourceFile(loader, path + "/" + name);
- }
-
- @Override
- public Source getSource() throws IOException {
- InputStream stream = loader.getResourceAsStream(path);
- BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
- return new LexerSource(reader, true);
- }
- }
-}
diff --git a/src/main/java/org/anarres/cpp/Source.java b/src/main/java/org/anarres/cpp/Source.java
deleted file mode 100644
index 817c162..0000000
--- a/src/main/java/org/anarres/cpp/Source.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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.util.Iterator;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import static org.anarres.cpp.Token.CCOMMENT;
-import static org.anarres.cpp.Token.CPPCOMMENT;
-import static org.anarres.cpp.Token.EOF;
-import static org.anarres.cpp.Token.NL;
-import static org.anarres.cpp.Token.WHITESPACE;
-
-/**
- * An input to the Preprocessor.
- *
- * Inputs may come from Files, Strings or other sources. The
- * preprocessor maintains a stack of Sources. Operations such as
- * file inclusion or token pasting will push a new source onto
- * the Preprocessor stack. Sources pop from the stack when they
- * are exhausted; this may be transparent or explicit.
- *
- * BUG: Error messages are not handled properly.
- */
-public abstract class Source implements Iterable<Token>, Closeable {
-
- private Source parent;
- private boolean autopop;
- private PreprocessorListener listener;
- private boolean active;
- private boolean werror;
-
- /* LineNumberReader */
-
- /*
- // We can't do this, since we would lose the LexerException
- private class Itr implements Iterator {
- private Token next = null;
- private void advance() {
- try {
- if (next != null)
- next = token();
- }
- catch (IOException e) {
- throw new UnsupportedOperationException(
- "Failed to advance token iterator: " +
- e.getMessage()
- );
- }
- }
- public boolean hasNext() {
- return next.getType() != EOF;
- }
- public Token next() {
- advance();
- Token t = next;
- next = null;
- return t;
- }
- public void remove() {
- throw new UnsupportedOperationException(
- "Cannot remove tokens from a Source."
- );
- }
- }
- */
- public Source() {
- this.parent = null;
- this.autopop = false;
- this.listener = null;
- this.active = true;
- this.werror = false;
- }
-
- /**
- * Sets the parent source of this source.
- *
- * Sources form a singly linked list.
- */
- /* pp */ void setParent(final Source parent, final boolean autopop) {
- this.parent = parent;
- this.autopop = autopop;
- }
-
- /**
- * Returns the parent source of this source.
- *
- * Sources form a singly linked list.
- */
- public final Source getParent() {
- return parent;
- }
-
-
- // @OverrideMustInvoke
- /* pp */ void init(final Preprocessor pp) {
- setListener(pp.getListener());
- this.werror = pp.getWarnings().contains(Warning.ERROR);
- }
-
- /**
- * Sets the listener for this Source.
- *
- * Normally this is set by the Preprocessor when a Source is
- * used, but if you are using a Source as a standalone object,
- * you may wish to call this.
- */
- public void setListener(final PreprocessorListener pl) {
- this.listener = pl;
- }
-
- /**
- * Returns the File currently being lexed.
- *
- * If this Source is not a {@link FileLexerSource}, then
- * it will ask the parent Source, and so forth recursively.
- * If no Source on the stack is a FileLexerSource, returns null.
- */
- @CheckForNull
- public String getPath() {
- final Source parent = getParent();
- if (parent != null)
- return parent.getPath();
- return null;
- }
-
- /**
- * Returns the human-readable name of the current Source.
- */
- @CheckForNull
- public String getName() {
- final Source parent = getParent();
- if (parent != null)
- return parent.getName();
- return null;
- }
-
- /**
- * Returns the current line number within this Source.
- */
- @Nonnegative
- public int getLine() {
- final Source parent = getParent();
- if (parent == null)
- return 0;
- return parent.getLine();
- }
-
- /**
- * Returns the current column number within this Source.
- */
- public int getColumn() {
- final Source parent = getParent();
- if (parent == null)
- return 0;
- return parent.getColumn();
- }
-
- /**
- * Returns true if this Source is expanding the given macro.
- *
- * This is used to prevent macro recursion.
- */
- /* pp */ boolean isExpanding(@Nonnull final Macro m) {
- final Source parent = getParent();
- if (parent != null)
- return parent.isExpanding(m);
- return false;
- }
-
- /**
- * Returns true if this Source should be transparently popped
- * from the input stack.
- *
- * Examples of such sources are macro expansions.
- */
- /* pp */ boolean isAutopop() {
- return autopop;
- }
-
- /**
- * Returns true if this source has line numbers.
- */
- /* pp */ boolean isNumbered() {
- return false;
- }
-
- /* This is an incredibly lazy way of disabling warnings when
- * the source is not active. */
- /* pp */ void setActive(final boolean b) {
- this.active = b;
- }
-
- /* pp */ boolean isActive() {
- return active;
- }
-
- /**
- * Returns the next Token parsed from this input stream.
- *
- * @see Token
- */
- @Nonnull
- public abstract Token token()
- throws IOException,
- LexerException;
-
- /**
- * Returns a token iterator for this Source.
- */
- @Override
- public Iterator<Token> iterator() {
- return new SourceIterator(this);
- }
-
- /**
- * Skips tokens until the end of line.
- *
- * @param white true if only whitespace is permitted on the
- * remainder of the line.
- * @return the NL token.
- */
- @Nonnull
- public Token skipline(final boolean white)
- throws IOException,
- LexerException {
- for (;;) {
- final Token tok = token();
- switch (tok.getType()) {
- case EOF:
- /* There ought to be a newline before EOF.
- * At least, in any skipline context. */
- /* XXX Are we sure about this? */
- warning(tok.getLine(), tok.getColumn(),
- "No newline before end of file");
- return new Token(NL,
- tok.getLine(), tok.getColumn(),
- "\n");
- // return tok;
- case NL:
- /* This may contain one or more newlines. */
- return tok;
- case CCOMMENT:
- case CPPCOMMENT:
- case WHITESPACE:
- break;
- default:
- /* XXX Check white, if required. */
- if (white)
- warning(tok.getLine(), tok.getColumn(),
- "Unexpected nonwhite token");
- break;
- }
- }
- }
-
- protected void error(final int line, final int column, final String msg)
- throws LexerException {
- if (listener != null)
- listener.handleError(this, line, column, msg);
- else
- throw new LexerException("Error at " + line + ":" + column + ": " + msg);
- }
-
- protected void warning(final int line, final int column, final String msg)
- throws LexerException {
- if (werror)
- error(line, column, msg);
- else if (listener != null)
- listener.handleWarning(this, line, column, msg);
- else
- throw new LexerException("Warning at " + line + ":" + column + ": " + msg);
- }
-
- public void close()
- throws IOException {
- }
-
-}
diff --git a/src/main/java/org/anarres/cpp/SourceIterator.java b/src/main/java/org/anarres/cpp/SourceIterator.java
deleted file mode 100644
index 82e36d9..0000000
--- a/src/main/java/org/anarres/cpp/SourceIterator.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.IOException;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import static org.anarres.cpp.Token.EOF;
-
-/**
- * An Iterator for {@link Source Sources},
- * returning {@link Token Tokens}.
- */
-public class SourceIterator implements Iterator<Token> {
-
- private final Source source;
- private Token tok;
-
- public SourceIterator(Source s) {
- this.source = s;
- this.tok = null;
- }
-
- /**
- * Rethrows IOException inside IllegalStateException.
- */
- private void advance() {
- try {
- if (tok == null)
- tok = source.token();
- } catch (LexerException e) {
- throw new IllegalStateException(e);
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
-
- /**
- * Returns true if the enclosed Source has more tokens.
- *
- * The EOF token is never returned by the iterator.
- * @throws IllegalStateException if the Source
- * throws a LexerException or IOException
- */
- public boolean hasNext() {
- advance();
- return tok.getType() != EOF;
- }
-
- /**
- * Returns the next token from the enclosed Source.
- *
- * The EOF token is never returned by the iterator.
- * @throws IllegalStateException if the Source
- * throws a LexerException or IOException
- */
- public Token next() {
- if (!hasNext())
- throw new NoSuchElementException();
- Token t = this.tok;
- this.tok = null;
- return t;
- }
-
- /**
- * Not supported.
- *
- * @throws UnsupportedOperationException.
- */
- public void remove() {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/src/main/java/org/anarres/cpp/State.java b/src/main/java/org/anarres/cpp/State.java
deleted file mode 100644
index e24195d..0000000
--- a/src/main/java/org/anarres/cpp/State.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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;
-
-/* pp */ class State {
-
- boolean parent;
- boolean active;
- boolean sawElse;
-
- /* pp */ State() {
- this.parent = true;
- this.active = true;
- this.sawElse = false;
- }
-
- /* pp */ State(State parent) {
- this.parent = parent.isParentActive() && parent.isActive();
- this.active = true;
- this.sawElse = false;
- }
-
- /* Required for #elif */
- /* pp */ void setParentActive(boolean b) {
- this.parent = b;
- }
-
- /* pp */ boolean isParentActive() {
- return parent;
- }
-
- /* pp */ void setActive(boolean b) {
- this.active = b;
- }
-
- /* pp */ boolean isActive() {
- return active;
- }
-
- /* pp */ void setSawElse() {
- sawElse = true;
- }
-
- /* pp */ boolean sawElse() {
- return sawElse;
- }
-
- @Override
- public String toString() {
- return "parent=" + parent
- + ", active=" + active
- + ", sawelse=" + sawElse;
- }
-}
diff --git a/src/main/java/org/anarres/cpp/StringLexerSource.java b/src/main/java/org/anarres/cpp/StringLexerSource.java
deleted file mode 100644
index 8640bc8..0000000
--- a/src/main/java/org/anarres/cpp/StringLexerSource.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.StringReader;
-
-/**
- * A Source for lexing a String.
- *
- * This class is used by token pasting, but can be used by user
- * code.
- */
-public class StringLexerSource extends LexerSource {
-
- /**
- * Creates a new Source for lexing the given String.
- *
- * @param ppvalid true if preprocessor directives are to be
- * honoured within the string.
- */
- public StringLexerSource(String string, boolean ppvalid) {
- super(new StringReader(string), ppvalid);
- }
-
- /**
- * Creates a new Source for lexing the given String.
- *
- * By default, preprocessor directives are not honoured within
- * the string.
- */
- public StringLexerSource(String string) {
- this(string, false);
- }
-
- @Override
- public String toString() {
- return "string literal";
- }
-}
diff --git a/src/main/java/org/anarres/cpp/Token.java b/src/main/java/org/anarres/cpp/Token.java
deleted file mode 100644
index 3e6eb3e..0000000
--- a/src/main/java/org/anarres/cpp/Token.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * 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;
-
-/**
- * A Preprocessor token.
- *
- * @see Preprocessor
- */
-public final class Token {
-
- // public static final int EOF = -1;
- private final int type;
- private int line;
- private int column;
- private final Object value;
- private final String text;
-
- public Token(int type, int line, int column,
- String text, Object value) {
- this.type = type;
- this.line = line;
- this.column = column;
- this.text = text;
- this.value = value;
- }
-
- public Token(int type, int line, int column, String text) {
- this(type, line, column, text, null);
- }
-
- /* pp */ Token(int type, String text, Object value) {
- this(type, -1, -1, text, value);
- }
-
- /* pp */ Token(int type, String text) {
- this(type, text, null);
- }
-
- /* pp */ Token(int type) {
- this(type, TokenType.getTokenText(type));
- }
-
- /**
- * Returns the semantic type of this token.
- */
- public int getType() {
- return type;
- }
-
- /* pp */ void setLocation(int line, int column) {
- this.line = line;
- this.column = column;
- }
-
- /**
- * Returns the line at which this token started.
- *
- * Lines are numbered from zero.
- */
- public int getLine() {
- return line;
- }
-
- /**
- * Returns the column at which this token started.
- *
- * Columns are numbered from zero.
- */
- public int getColumn() {
- return column;
- }
-
- /**
- * Returns the original or generated text of this token.
- *
- * This is distinct from the semantic value of the token.
- *
- * @see #getValue()
- */
- public String getText() {
- return text;
- }
-
- /**
- * Returns the semantic value of this token.
- *
- * For strings, this is the parsed String.
- * For integers, this is an Integer object.
- * For other token types, as appropriate.
- *
- * @see #getText()
- */
- public Object getValue() {
- return value;
- }
-
- /**
- * Returns a description of this token, for debugging purposes.
- */
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
-
- buf.append('[').append(getTokenName(type));
- if (line != -1) {
- buf.append('@').append(line);
- if (column != -1)
- buf.append(',').append(column);
- }
- buf.append("]:");
- if (text != null)
- buf.append('"').append(text).append('"');
- else if (type > 3 && type < 256)
- buf.append((char) type);
- else
- buf.append('<').append(type).append('>');
- if (value != null)
- buf.append('=').append(value);
- return buf.toString();
- }
-
- /**
- * Returns the descriptive name of the given token type.
- *
- * This is mostly used for stringification and debugging.
- */
- public static String getTokenName(int type) {
- return TokenType.getTokenName(type);
- }
-
- public static final int AND_EQ = 257;
- public static final int ARROW = 258;
- public static final int CHARACTER = 259;
- public static final int CCOMMENT = 260;
- public static final int CPPCOMMENT = 261;
- public static final int DEC = 262;
- public static final int DIV_EQ = 263;
- public static final int ELLIPSIS = 264;
- public static final int EOF = 265;
- public static final int EQ = 266;
- public static final int GE = 267;
- public static final int HASH = 268;
- public static final int HEADER = 269;
- public static final int IDENTIFIER = 270;
- public static final int INC = 271;
- public static final int NUMBER = 272;
- public static final int LAND = 273;
- public static final int LAND_EQ = 274;
- public static final int LE = 275;
- public static final int LITERAL = 276;
- public static final int LOR = 277;
- public static final int LOR_EQ = 278;
- public static final int LSH = 279;
- public static final int LSH_EQ = 280;
- public static final int MOD_EQ = 281;
- public static final int MULT_EQ = 282;
- public static final int NE = 283;
- public static final int NL = 284;
- public static final int OR_EQ = 285;
- public static final int PASTE = 286;
- public static final int PLUS_EQ = 287;
- public static final int RANGE = 288;
- public static final int RSH = 289;
- public static final int RSH_EQ = 290;
- public static final int SQSTRING = 291;
- public static final int STRING = 292;
- public static final int SUB_EQ = 293;
- public static final int WHITESPACE = 294;
- public static final int XOR_EQ = 295;
- public static final int M_ARG = 296;
- public static final int M_PASTE = 297;
- public static final int M_STRING = 298;
- public static final int P_LINE = 299;
- public static final int INVALID = 300;
-
- /** The position-less space token. */
- /* pp */ static final Token space = new Token(WHITESPACE, -1, -1, " ");
-}
diff --git a/src/main/java/org/anarres/cpp/TokenSnifferSource.java b/src/main/java/org/anarres/cpp/TokenSnifferSource.java
deleted file mode 100644
index 21e1cb8..0000000
--- a/src/main/java/org/anarres/cpp/TokenSnifferSource.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.IOException;
-import java.util.List;
-import static org.anarres.cpp.Token.EOF;
-
-@Deprecated
-/* pp */ class TokenSnifferSource extends Source {
-
- private final List<Token> target;
-
- /* pp */ TokenSnifferSource(List<Token> target) {
- this.target = target;
- }
-
- public Token token()
- throws IOException,
- LexerException {
- Token tok = getParent().token();
- if (tok.getType() != EOF)
- target.add(tok);
- return tok;
- }
-
- @Override
- public String toString() {
- return getParent().toString();
- }
-}
diff --git a/src/main/java/org/anarres/cpp/TokenType.java b/src/main/java/org/anarres/cpp/TokenType.java
deleted file mode 100644
index 86df097..0000000
--- a/src/main/java/org/anarres/cpp/TokenType.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.anarres.cpp;
-
-import java.util.ArrayList;
-import java.util.List;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import static org.anarres.cpp.Token.*;
-
-/**
- *
- * @author shevek
- */
-/* pp */ class TokenType {
-
- private static final List<TokenType> TYPES = new ArrayList<TokenType>();
-
- private static void addTokenType(@Nonnegative int type, @Nonnull String name, @CheckForNull String text) {
- while (TYPES.size() <= type)
- TYPES.add(null);
- TYPES.set(type, new TokenType(name, text));
- }
-
- private static void addTokenType(@Nonnegative int type, @Nonnull String name) {
- addTokenType(type, name, null);
- }
-
- @CheckForNull
- public static TokenType getTokenType(@Nonnegative int type) {
- try {
- return TYPES.get(type);
- } catch (IndexOutOfBoundsException e) {
- return null;
- }
- }
-
- @Nonnull
- public static String getTokenName(@Nonnegative int type) {
- if (type < 0)
- return "Invalid" + type;
- TokenType tokenType = getTokenType(type);
- if (tokenType == null)
- return "Unknown" + type;
- return tokenType.getName();
- }
-
- @CheckForNull
- public static String getTokenText(@Nonnegative int type) {
- TokenType tokenType = getTokenType(type);
- if (tokenType == null)
- return null;
- return tokenType.getText();
- }
-
- static {
- for (int i = 0; i < 255; i++) {
- String text = String.valueOf((char) i);
- addTokenType(i, text, text);
- }
- addTokenType(AND_EQ, "AND_EQ", "&=");
- addTokenType(ARROW, "ARROW", "->");
- addTokenType(CHARACTER, "CHARACTER");
- addTokenType(CCOMMENT, "CCOMMENT");
- addTokenType(CPPCOMMENT, "CPPCOMMENT");
- addTokenType(DEC, "DEC", "--");
- addTokenType(DIV_EQ, "DIV_EQ", "/=");
- addTokenType(ELLIPSIS, "ELLIPSIS", "...");
- addTokenType(EOF, "EOF");
- addTokenType(EQ, "EQ", "==");
- addTokenType(GE, "GE", ">=");
- addTokenType(HASH, "HASH", "#");
- addTokenType(HEADER, "HEADER");
- addTokenType(IDENTIFIER, "IDENTIFIER");
- addTokenType(INC, "INC", "++");
- addTokenType(NUMBER, "NUMBER");
- addTokenType(LAND, "LAND", "&&");
- addTokenType(LAND_EQ, "LAND_EQ", "&&=");
- addTokenType(LE, "LE", "<=");
- addTokenType(LITERAL, "LITERAL");
- addTokenType(LOR, "LOR", "||");
- addTokenType(LOR_EQ, "LOR_EQ", "||=");
- addTokenType(LSH, "LSH", "<<");
- addTokenType(LSH_EQ, "LSH_EQ", "<<=");
- addTokenType(MOD_EQ, "MOD_EQ", "%=");
- addTokenType(MULT_EQ, "MULT_EQ", "*=");
- addTokenType(NE, "NE", "!=");
- addTokenType(NL, "NL");
- addTokenType(OR_EQ, "OR_EQ", "|=");
- addTokenType(PASTE, "PASTE", "##");
- addTokenType(PLUS_EQ, "PLUS_EQ", "+=");
- addTokenType(RANGE, "RANGE", "..");
- addTokenType(RSH, "RSH", ">>");
- addTokenType(RSH_EQ, "RSH_EQ", ">>=");
- addTokenType(SQSTRING, "SQSTRING");
- addTokenType(STRING, "STRING");
- addTokenType(SUB_EQ, "SUB_EQ", "-=");
- addTokenType(WHITESPACE, "WHITESPACE");
- addTokenType(XOR_EQ, "XOR_EQ", "^=");
- addTokenType(M_ARG, "M_ARG");
- addTokenType(M_PASTE, "M_PASTE");
- addTokenType(M_STRING, "M_STRING");
- addTokenType(P_LINE, "P_LINE");
- addTokenType(INVALID, "INVALID");
- }
-
- private final String name;
- private final String text;
-
- /* pp */ TokenType(@Nonnull String name, @CheckForNull String text) {
- this.name = name;
- this.text = text;
- }
-
- @Nonnull
- public String getName() {
- return name;
- }
-
- @CheckForNull
- public String getText() {
- return text;
- }
-}
diff --git a/src/main/java/org/anarres/cpp/VirtualFile.java b/src/main/java/org/anarres/cpp/VirtualFile.java
deleted file mode 100644
index aee1cad..0000000
--- a/src/main/java/org/anarres/cpp/VirtualFile.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * 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.IOException;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nonnull;
-
-/**
- * An extremely lightweight virtual file interface.
- */
-public interface VirtualFile {
-
- // public String getParent();
- public boolean isFile();
-
- @Nonnull
- public String getPath();
-
- @Nonnull
- public String getName();
-
- @CheckForNull
- public VirtualFile getParentFile();
-
- @Nonnull
- public VirtualFile getChildFile(String name);
-
- @Nonnull
- public Source getSource() throws IOException;
-}
diff --git a/src/main/java/org/anarres/cpp/VirtualFileSystem.java b/src/main/java/org/anarres/cpp/VirtualFileSystem.java
deleted file mode 100644
index 9c77d30..0000000
--- a/src/main/java/org/anarres/cpp/VirtualFileSystem.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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 javax.annotation.Nonnull;
-
-/**
- * An extremely lightweight virtual file system interface.
- */
-public interface VirtualFileSystem {
-
- @Nonnull
- public VirtualFile getFile(@Nonnull String path);
-
- @Nonnull
- public VirtualFile getFile(@Nonnull String dir, @Nonnull String name);
-}
diff --git a/src/main/java/org/anarres/cpp/Warning.java b/src/main/java/org/anarres/cpp/Warning.java
deleted file mode 100644
index 80d184a..0000000
--- a/src/main/java/org/anarres/cpp/Warning.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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;
-
-/**
- * Warning classes which may optionally be emitted by the Preprocessor.
- */
-public enum Warning {
-
- TRIGRAPHS,
- // TRADITIONAL,
- IMPORT,
- UNDEF,
- UNUSED_MACROS,
- ENDIF_LABELS,
- ERROR,
- // SYSTEM_HEADERS
-}