summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--etc/global.xml4
-rw-r--r--etc/targets/global-tar.xml28
-rw-r--r--lib/runtime/getopt/gnu.getopt.jarbin0 -> 13625 bytes
-rw-r--r--src/java/org/anarres/cpp/LexerSource.java23
-rw-r--r--src/java/org/anarres/cpp/Main.java273
-rw-r--r--src/java/org/anarres/cpp/Preprocessor.java10
-rw-r--r--src/java/org/anarres/cpp/Version.java51
-rw-r--r--src/java/org/anarres/cpp/Warning.java12
-rw-r--r--src/scripts/release.sh8
9 files changed, 377 insertions, 32 deletions
diff --git a/etc/global.xml b/etc/global.xml
index 052ea6b..41bf829 100644
--- a/etc/global.xml
+++ b/etc/global.xml
@@ -9,11 +9,9 @@
<property file="${global.dir.etc}/log4j.properties" />
<path id="compile-classpath">
- <!--
<fileset dir="${global.dir.lib}">
- <include name="**/*.jar"/>
+ <include name="runtime/**/*.jar"/>
</fileset>
- -->
</path>
<path id="runtime-classpath">
diff --git a/etc/targets/global-tar.xml b/etc/targets/global-tar.xml
index 1b053ae..05412be 100644
--- a/etc/targets/global-tar.xml
+++ b/etc/targets/global-tar.xml
@@ -2,7 +2,7 @@
<project name="global-tar" basedir=".">
- <target name="global-tar" depends="global-jar,global-javadoc">
+ <target name="global-tar-dir" depends="global-jar">
<mkdir dir="${global.dir.build.dist}" />
<mkdir dir="${global.dir.build.tar}/lib" />
<mkdir dir="${global.dir.build.tar}/bin" />
@@ -12,6 +12,9 @@
<fileset dir="${global.dir.lib}/log4j">
<include name="**/*.jar" />
</fileset>
+ <fileset dir="${global.dir.lib}/runtime">
+ <include name="**/*.jar" />
+ </fileset>
<mapper type="flatten" />
</copy>
@@ -24,19 +27,6 @@
</fileset>
</copy>
- <copy todir="${global.dir.build.tar}/docs/api">
- <fileset dir="${global.dir.build.javadoc}" />
- </copy>
-
-<!--
- <copy todir="${global.dir.build.tar}/docs/examples">
- <fileset
- dir="${global.dir.build.java}/org/anarres/cpp/examples">
- <include name="**" />
- </fileset>
- </copy>
--->
-
<chmod perm="a+x">
<fileset dir="${global.dir.build.tar}/bin">
<include name="**/*.pl"/>
@@ -44,9 +34,19 @@
<fileset dir="${global.dir.build.tar}">
<include name="*.sh"/>
</fileset>
+ <fileset dir="${global.dir.build.tar}">
+ <include name="jcpp"/>
+ </fileset>
</chmod>
<!-- <runtarget target="global-inject" /> -->
+ </target>
+
+ <target name="global-tar" depends="global-tar-dir,global-javadoc">
+
+ <copy todir="${global.dir.build.tar}/docs/api">
+ <fileset dir="${global.dir.build.javadoc}" />
+ </copy>
<tar
destfile="${global.file.bintar}"
diff --git a/lib/runtime/getopt/gnu.getopt.jar b/lib/runtime/getopt/gnu.getopt.jar
new file mode 100644
index 0000000..1aea24b
--- /dev/null
+++ b/lib/runtime/getopt/gnu.getopt.jar
Binary files differ
diff --git a/src/java/org/anarres/cpp/LexerSource.java b/src/java/org/anarres/cpp/LexerSource.java
index a291bff..51b5c07 100644
--- a/src/java/org/anarres/cpp/LexerSource.java
+++ b/src/java/org/anarres/cpp/LexerSource.java
@@ -297,7 +297,7 @@ public class LexerSource extends Source {
if (e != '\'') {
unread(e);
error("Illegal character constant");
- /* XXX We could do some patching up here? */
+ /* XXX We should consume the rest of the line here. */
return new Token(ERROR, text.toString(), null);
}
text.append('\'');
@@ -306,8 +306,6 @@ public class LexerSource extends Source {
text.toString(), Character.valueOf((char)d));
}
- /* XXX This strips the enclosing quotes from the
- * returned value. */
private Token string(char open, char close)
throws IOException,
LexerException {
@@ -558,11 +556,24 @@ public class LexerSource extends Source {
break;
case '%':
- tok = cond('=', MOD_EQ, '%');
+ d = read();
+ if (d == '=')
+ tok = new Token(MOD_EQ);
+ else if (d == '>')
+ tok = new Token('}'); // digraph
+ else if (d == ':')
+ tok = new Token('#'); // digraph
+ else // XXX Deal with %:%: -> ##
+ unread(d);
break;
case ':':
/* :: */
+ d = read();
+ if (d == '>')
+ tok = new Token(']'); // digraph
+ else
+ unread(d);
break;
case '<':
@@ -575,6 +586,10 @@ public class LexerSource extends Source {
tok = new Token(LE);
else if (d == '<')
tok = cond('=', LSH_EQ, LSH);
+ else if (d == ':')
+ tok = new Token('['); // digraph
+ else if (d == '%')
+ tok = new Token('{'); // digraph
else
unread(d);
}
diff --git a/src/java/org/anarres/cpp/Main.java b/src/java/org/anarres/cpp/Main.java
index cec7a37..cf61ecd 100644
--- a/src/java/org/anarres/cpp/Main.java
+++ b/src/java/org/anarres/cpp/Main.java
@@ -24,12 +24,17 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.Stack;
+import gnu.getopt.Getopt;
+import gnu.getopt.LongOpt;
+
import static org.anarres.cpp.Token.*;
/**
@@ -37,7 +42,275 @@ import static org.anarres.cpp.Token.*;
*/
public class Main {
+ protected static class Option extends LongOpt {
+ private String eg;
+ private String help;
+ public Option(String word, int arg, int ch,
+ String eg, String help) {
+ super(word, arg, null, ch);
+ this.eg = eg;
+ this.help = help;
+ }
+ }
+
+ private List<String> i_default;
+ private List<String> i_system;
+ private List<String> i_user;
+ private List<String> i_quote;
+ private Map<String,String> d_default;
+ private Map<String,String> d_user;
+ private Set<Warning> warnings;
+ private List<String> f_include;
+
+ private static final Option[] OPTS = new Option[] {
+ new Option("help", LongOpt.NO_ARGUMENT, 'h', null,
+ "Displays help and usage information."),
+ new Option("define", LongOpt.REQUIRED_ARGUMENT, 'D', "name=definition",
+ "Defines the given macro."),
+ new Option("undefine", LongOpt.REQUIRED_ARGUMENT, 'U', "name",
+ "Undefines the given macro, previously either builtin or defined using -D."),
+ new Option("incdir", LongOpt.REQUIRED_ARGUMENT, 'I', "dir",
+ "Adds the directory dir to the list of directories to be searched for header files."),
+ new Option("warning", LongOpt.REQUIRED_ARGUMENT, 'W', "type",
+ "Enables the named warning class (" + getWarnings() + ")."),
+ new Option("nowarnings", LongOpt.NO_ARGUMENT, 'w', null,
+ "Disables ALL warnings."),
+ new Option("version", LongOpt.NO_ARGUMENT, 'V', null,
+ "Prints jcpp's version number (" + Version.getVersion() + ")"),
+ };
+
+ 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(OPTS, args);
+ }
+
+ public Main() {
+ i_default = new ArrayList<String>();
+ i_system = new ArrayList<String>();
+ i_user = new ArrayList<String>();
+ i_quote = new ArrayList<String>();
+ d_default = new HashMap<String,String>();
+ d_user = new HashMap<String,String>();
+ warnings = EnumSet.noneOf(Warning.class);
+ }
+
+ public void run(Option[] opts, String[] args) throws Exception {
+ String sopts = getShortOpts(opts);
+ Getopt g = new Getopt("jcpp", args, sopts, opts);
+ int c;
+ String arg;
+ int idx;
+
+ GETOPT: while ((c = g.getopt()) != -1) {
+ switch (c) {
+ case 'D':
+ arg = g.getOptarg();
+ idx = arg.indexOf('=');
+ if (idx == -1)
+ d_user.put(arg, "1");
+ else
+ d_user.put(arg.substring(0, idx),
+ arg.substring(idx + 1));
+ break;
+ case 'U':
+ d_default.remove(g.getOptarg());
+ d_user.remove(g.getOptarg());
+ break;
+ case 'I':
+ i_user.add(g.getOptarg());
+ break;
+ case 'W':
+ arg = g.getOptarg().toUpperCase();
+ arg = arg.replace('-', '_');
+ if (arg.equals("all"))
+ warnings = EnumSet.allOf(Warning.class);
+ else
+ warnings.add(Enum.valueOf(Warning.class, arg));
+ break;
+ case 'w':
+ warnings = EnumSet.noneOf(Warning.class);
+ break;
+ case 'V':
+ System.out.println("Anarres Java C Preprocessor version " + Version.getVersion());
+ System.exit(0);
+ throw new Exception("Exited");
+ case 'h':
+ usage(getClass().getName(), opts);
+ System.exit(1);
+ throw new Exception("Exited");
+ default:
+ case '?':
+ throw new Exception("Illegal option " + c);
+ }
+ }
+
+ File file = new File(args[g.getOptind()]);
+ Source source = new FileLexerSource(file);
+ Preprocessor pp = new Preprocessor(source);
+
+ /* XXX Warnings, include-path, include-files. */
+
+ for (int i = g.getOptind() + 1; i < args.length; i++) {
+ /* XXX Wrong, needs to concat them not push them. */
+ /* XXX Reverse this list. */
+ pp.addSource(new FileLexerSource(new File(args[i])));
+ }
+
+ for (Map.Entry<String,String> e : d_default.entrySet())
+ pp.addMacro(e.getKey(), e.getValue());
+ for (Map.Entry<String,String> e : d_user.entrySet())
+ pp.addMacro(e.getKey(), e.getValue());
+
+ /* XXX Include paths. */
+
+ try {
+ for (;;) {
+ Token tok = pp.token();
+ if (tok != null && tok.getType() == Token.EOF)
+ break;
+ System.out.print(tok.getText());
+ }
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ Source s = pp.getSource();
+ while (s != null) {
+ System.out.println(" -> " + s);
+ s = s.getParent();
+ }
+ }
+
+ }
+
+
+ private static String getShortOpts(Option[] opts)
+ throws Exception {
+ StringBuilder buf = new StringBuilder();
+ for (int i = 0; i < opts.length; i++) {
+ char c = (char)opts[i].getVal();
+ for (int j = 0; j < buf.length(); j++)
+ if (buf.charAt(j) == c)
+ throw new Exception(
+ "Duplicate short option " + c
+ );
+ buf.append(c);
+ switch (opts[i].getHasArg()) {
+ case LongOpt.NO_ARGUMENT:
+ break;
+ case LongOpt.OPTIONAL_ARGUMENT:
+ buf.append("::");
+ break;
+ case LongOpt.REQUIRED_ARGUMENT:
+ buf.append(":");
+ break;
+ }
+ }
+ return buf.toString();
+ }
+
+ /* This is incomplete but nearly there. */
+ /**
+ * Wraps a string.
+ *
+ * The output form is:
+ * <pre>
+ * prefix in[0]
+ * &lt;--indent-&gt; in[1]
+ * &lt;--indent-&gt; in[2]
+ * &lt;-----width----&gt;
+ * </pre>
+ */
+ /* XXX There's some of this in commons. */
+ private static String wrap(String in, String prefix,
+ int indent, int width) {
+ StringBuilder buf = new StringBuilder(prefix);
+
+ while (buf.length() < indent)
+ buf.append(' ');
+
+ int start = 0;
+
+ while (start < in.length()) {
+ while (start < in.length() &&
+ Character.isWhitespace(in.charAt(start)))
+ start++;
+
+ int end = start + width - indent;
+
+ if (end > in.length()) {
+ buf.append(in.substring(start));
+ break;
+ }
+
+ int idx = end;
+ while (!Character.isWhitespace(in.charAt(idx)))
+ idx--;
+
+ if (idx == start) {
+ idx = end - 1;
+ buf.append(in.substring(start, idx));
+ buf.append('-');
+ }
+ else {
+ buf.append(in.substring(start, idx));
+ start = idx;
+ }
+
+ start = idx;
+ }
+
+ return buf.toString();
+ }
+
+ private static void usage(String command, Option[] options) {
+ StringBuilder text = new StringBuilder("Usage: ");
+ text.append(command).append('\n');
+ for (int i = 0; i < options.length; i++) {
+ StringBuilder line = new StringBuilder();
+ Option opt = options[i];
+ line.append(" --").append(opt.getName());
+ switch (opt.getHasArg()) {
+ case LongOpt.NO_ARGUMENT:
+ break;
+ case LongOpt.OPTIONAL_ARGUMENT:
+ line.append("[=").append(opt.eg).append(']');
+ break;
+ case LongOpt.REQUIRED_ARGUMENT:
+ line.append('=').append(opt.eg);
+ break;
+ }
+ line.append(" (-").append((char)opt.getVal()).append(")");
+ if (line.length() < 30) {
+ while (line.length() < 30)
+ line.append(' ');
+ }
+ else {
+ line.append('\n');
+ for (int j = 0; j < 30; j++)
+ line.append(' ');
+ }
+ /* This should use wrap. */
+ line.append(opt.help);
+ line.append('\n');
+ text.append(line);
+ }
+
+ System.out.println(text);
+ }
+
+
+
+ public static void oldmain(String[] args) throws Exception {
List<String> path = new ArrayList<String>();
path.add("/usr/include");
path.add("/usr/local/include");
diff --git a/src/java/org/anarres/cpp/Preprocessor.java b/src/java/org/anarres/cpp/Preprocessor.java
index de6d01b..17d6c04 100644
--- a/src/java/org/anarres/cpp/Preprocessor.java
+++ b/src/java/org/anarres/cpp/Preprocessor.java
@@ -329,7 +329,6 @@ public class Preprocessor {
LexerException {
Token tok;
do {
- /* XXX This _should_ never be a NL token, I think. */
tok = source_token();
} while (isWhite(tok));
return tok;
@@ -769,7 +768,7 @@ public class Preprocessor {
dir = new File("/");
File file = new File(dir, name);
// System.err.println("Include: " + file);
- if (file.exists()) {
+ if (file.exists() && file.isFile()) {
push_source(new FileLexerSource(file), true);
return;
}
@@ -780,7 +779,7 @@ public class Preprocessor {
File file = new File(
path.get(i) + File.separator + name
);
- if (file.exists()) {
+ if (file.exists() && file.isFile()) {
// System.err.println("Include: " + file);
push_source(new FileLexerSource(file), true);
return;
@@ -807,11 +806,8 @@ public class Preprocessor {
* Backslashes must not be treated as escapes here. */
StringBuilder buf = new StringBuilder((String)tok.getValue());
HEADER: for (;;) {
- tok = _token(); /* Do macros but nothing else. */
+ tok = token_nonwhite();
switch (tok.getType()) {
- case WHITESPACE:
- case COMMENT:
- continue;
case STRING:
buf.append((String)tok.getValue());
break;
diff --git a/src/java/org/anarres/cpp/Version.java b/src/java/org/anarres/cpp/Version.java
new file mode 100644
index 0000000..6780506
--- /dev/null
+++ b/src/java/org/anarres/cpp/Version.java
@@ -0,0 +1,51 @@
+package org.anarres.cpp;
+
+/**
+ * System version metadata for Anarres Java C Preprocessor ${version}.
+ *
+ * This class contains a main() and may be run to print the version.
+ */
+public class Version {
+
+ /* Don't instantiate me */
+ private Version() {
+ }
+
+ private static final String VERSION = "${version}";
+
+ private static final int major;
+ private static final int minor;
+ private static final int patch;
+
+ static {
+ String[] tmp = VERSION.split("\\.");
+ major = Integer.parseInt(tmp[0]);
+ minor = Integer.parseInt(tmp[1]);
+ patch = Integer.parseInt(tmp[2]);
+ }
+
+ public static String getVersion() {
+ return VERSION;
+ }
+
+ public static int getMajor() {
+ return major;
+ }
+
+ public static int getMinor() {
+ return minor;
+ }
+
+ public static int getPatch() {
+ return patch;
+ }
+
+ public static void main(String[] args) {
+ System.out.println("Version " + VERSION);
+ System.out.println("getVersion() returns " + getVersion());
+ System.out.println("getMajor() returns " + getMajor());
+ System.out.println("getMinor() returns " + getMinor());
+ System.out.println("getPatch() returns " + getPatch());
+ }
+
+}
diff --git a/src/java/org/anarres/cpp/Warning.java b/src/java/org/anarres/cpp/Warning.java
new file mode 100644
index 0000000..a6450fb
--- /dev/null
+++ b/src/java/org/anarres/cpp/Warning.java
@@ -0,0 +1,12 @@
+package org.anarres.cpp;
+
+public enum Warning {
+ TRIGRAPHS,
+ TRADITIONAL,
+ IMPORT,
+ UNDEF,
+ UNUSED_MACROS,
+ ENDIF_LABELS,
+ ERROR,
+ SYSTEM_HEADERS
+}
diff --git a/src/scripts/release.sh b/src/scripts/release.sh
index 6393a95..620ce96 100644
--- a/src/scripts/release.sh
+++ b/src/scripts/release.sh
@@ -1,4 +1,4 @@
-scp build/dist/anarres-cpp-*.tar.gz [email protected]:public_html/projects/jcpp
-scp -r build/javadoc/ [email protected]:public_html/projects/jcpp
-cp build/tar/lib/anarres-cpp.jar /home/shevek/java/iengine/lib/jcpp
-cp build/tar/lib/anarres-cpp.jar /home/shevek/java/karma/trunk/lib/dp
+scp build/dist/anarres-cpp-*.tar.gz [email protected]:public_html/projects/jcpp/
+scp -r build/javadoc/ [email protected]:public_html/projects/jcpp/
+cp build/tar/lib/anarres-cpp.jar /home/shevek/java/iengine/lib/runtime/jcpp/
+cp build/tar/lib/anarres-cpp.jar /home/shevek/java/karma/trunk/lib/dp/